library(readr)
library(qvalue)
library(explore)
library(maditr)
library(GEOquery)
library(Matrix)
library(ggplot2)
library(dplyr)
library(pheatmap)
library(RColorBrewer)
library(celldex)
library(biomaRt)
library(org.Hs.eg.db)
library(plotly)
library(DESeq2)
library(msigdbr)
library(ape)
library(GSVA)
library(sva)
library(readxl)
library(clusterProfiler)
library(pheatmap)
library(gplots)
library(EnhancedVolcano)
library(metaRNASeq)
library(ggbeeswarm)
library(editData)
library(tidyverse)
library(corrr)
library(ggcorrplot)
library(FactoMineR)
library(factoextra)
library(esquisse)
library(corto)
library(circlize)
library(ComplexHeatmap)
library(janitor)

1. Preparação dos dados

2. Definir padrões de figuras

####Cores

#Vaccines
ann_colors = list(
  vaccine = c(
  "BBIBP" = "#dee2e6",
  "BNT" = "#56cfe1",
  "ChAd" = "#80ffdb",
  "ChAd-BNT" = "#5e60ce",
  "ZF2001" = "#b5179e",
  "INFECTION" = "#ff4d6d",
  "INFECTION-VACCINE"= "#ffccd5"),
  dose = c(
    "NA" = "white",
    "0" = "white",
    "1" = "#56cfe1",
    "2" = "#5978d4",
    "3" = "#b5179e"),
  day = c(
    "0" = "white",
    "1" = "#caf0f8",
    "2" = "#ade8f4",
    "3" = "#90e0ef",
    "4" = "#6CD5EA",
    "5" = "#48cae4",
    "6" = "#00b4d8",
    "7" = "#0096c7",
    "10" = "#0087BF",
    "14" = "#0077b6",
    "26" = "#015BA0",
    "28" = "#023e8a",
    "51" = "#03045e"),
  type = c('IN'= "#e5e5e5", #1st Gen  vaccines
           'SU' = "#00a896",
           'VV' = "#72efdd", #3rd Gen vaccines
           'RNA' = "#56cfe1",
           'VV-RNA' = "#5e60ce", #Heterologous
           'IN-SU' = "#b5179e",
           'INFECTION'= "#da1e37"), #Infection
  regimen = c('HO' = "grey90",
              'HE' = "#8d99ae",
              "V-I-V" = "#36248f",
              "V-I" = "#D7B0EE",
              "I-V-I" = "#7400b8",
              "I-I" = "#5390d9",
              "I" = "#64dfdf"),
  infection = c("none" = "white",
                "1" = "#56cfe1",
                "2" = "#5e60ce"),
  variant = c("NA" = "white",
              "Beta" = "#72efdd",
              "Omicron" = "#5e60ce"),
  severity = c("A (9%) MI (81%) MO (0) S (4%)" = "#caf0f8",
               "A (29%) MI (57%) MO (14) S (0%)" = "#56cfe1",
               "A (0%) MI (89%) MO (11%) S (0%)" = "#72efdd",
               "A (9%) MI (47%) MO (21%) S (3%)" = "#64dfdf"
               "S" = "#5e60ce",
Error: unexpected string constant in:
"               "A (9%) MI (47%) MO (21%) S (3%)" = "#64dfdf"
               "S""

3. Seleção de estudos

# GSE189039
# GSE201530

3.1 Baixar dados

Ler arquivos e transformar em tabela

Abra a lista do estudo e analise suas informações. Ao descompactar, surgem diversos arquivos “.featureCounts.txt.gz”, que devem ser descompactados. Para descompactar a lista de arquivos, use um loop.

4. Análise de dados

4.1. Análise de expressão genica diferencial

Padronizando tabela de counts

Metadata

A tabela de counts fornecida pelo estudo é nomeada com o Subject ID + Timepoint e não com o codigo GSM. Por isso, teremos de tratar a tabela de metadados. Além disso, ela não possui a coluna de idade. É possível manipular estes dados no excel.

DESEQ2

Preparando dados

GSE201530

###### Padronize as variáveis 
countData <- gse201530_counts_ready
Error: object 'gse201530_counts_ready' not found

Executando DESEQ2

Comparando tempos e condições

Nesta comparação, são encontradas DEGs de cada vacina individual nos diferentes tempos. Para comparar uma vacina com a outra em diferentes tempos, é necessário usar os argumentos “contrast” ou “name”.

#H-BNT-I
# contrast = c("disease_time", "H.BNT.I_D1", "H_D0")
# contrast = c("disease_time", "H.BNT.I_D2", "H_D0") (NAO DEU)
# contrast = c("disease_time", "H.BNT.I_D3", "H_D0")
# contrast = c("disease_time", "H.BNT.I_D4", "H_D0")

#I-BNT-I
# contrast = c("disease_time", "I.BNT.I_D2", "H_D0")
# contrast = c("disease_time", "I.BNT.I_D5", "H_D0")

#H-I
# contrast = c("disease_time", "H.I_D1", "H_D0")

#H-I-I
# contrast = c("disease_time", "H.I.I_D2", "H_D0")
#I-I
# contrast = c("disease_time", "I.I_D1", "H_D0")
# contrast = c("disease_time", "I.I_D3", "H_D0")
# contrast = c("disease_time", "I.I_D5", "H_D0")

H_BNT_I

#H_BNT_I_D1
gse201530_H_BNT_I_D1 = results(dds, contrast = c("disease_time", "H.BNT.I_D1", "H_D0")) %>% 
  as.data.frame() %>% 
  arrange(padj) %>% 
  mutate(condition = "H-BNT-I (D1)",
         day = 1,
         vaccine = "H-BNT-I",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")
Error in h(simpleError(msg, call)) : 
  error in evaluating the argument 'x' in selecting a method for function 'as.data.frame': disease_time should be the name of a factor in the colData of the DESeqDataSet

I_BNT_I

######### I_BNT_I

#D2
gse201530_I_BNT_I_D2 = results(dds, contrast = c("disease_time", "I.BNT.I_D2", "H_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "I-BNT-I (D2)",
         day = 2,
         vaccine = "I-BNT-I",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse201530_I_BNT_I_D2, file = "gse201530_I_BNT_I_D2_DEGs.csv")


#D5
gse201530_I_BNT_I_D5 = results(dds, contrast = c("disease_time", "I.BNT.I_D5", "H_D0")) %>%
  as.data.frame() %>%
  filter(padj < 0.05) %>%
  arrange(padj) %>%
  mutate(condition = "I-BNT-I (D5)",
         day = 5,
         vaccine = "I-BNT-I",
         direction = ifelse(log2FoldChange >= 1, "UP",
                            ifelse(log2FoldChange <= -1, "DOWN",
                                   "NEUTRAL"))) %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse201530_I_BNT_I_D5, file = "gse201530_H_BNT_I_D5_DEGs.csv")

gse201530_I_BNT_I = bind_rows(gse201530_I_BNT_I_D2,
                            gse201530_I_BNT_I_D5)

write.csv(gse201530_I_BNT_I, "gse201530_I_BNT_I.csv")

H-I

######### H-I

#D1
gse201530_H_I_D1 = results(dds, contrast = c("disease_time", "H.I_D1", "H_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "H-I (D1)",
         day = 1,
         vaccine = "H-I",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse201530_H_I_D1, file = "gse201530_H_I_D1_DEGs-PF.csv")


#D5
gse201530_H_I_D5 = results(dds, contrast = c("disease_time", "I.BNT.I_D5", "H_D0")) %>%
  as.data.frame() %>%
  filter(padj < 0.05) %>%
  arrange(padj) %>%
  mutate(condition = "H-I (D5)",
         day = 5,
         vaccine = "H-I",
         direction = ifelse(log2FoldChange >= 1, "UP",
                            ifelse(log2FoldChange <= -1, "DOWN",
                                   "NEUTRAL"))) %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse201530_H_I_D5, file = "gse201530_H_I_D5_DEGs-PF.csv")

gse201530_H_I = bind_rows(gse201530_I_BNT_I_D2,
                            gse201530_I_BNT_I_D5)

write.csv(gse201530_H_I, "gse201530_H_I.csv")

H-I-I


######### H-I-I
#D2
gse201530_H_I_I_D2 = results(dds, contrast = c("disease_time", "H.I.I_D2", "H_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "H-I-I (D2)",
         day = 2,
         vaccine = "H-I-I",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse201530_H_I_I_D2, file = "gse201530_H_I_I_D2_DEGs-PF.csv")

I-I


######### I-I
#D1
gse201530_I_I_D1 = results(dds, contrast = c("disease_time", "I.I_D1", "H_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "I-I (D1)",
         day = 1,
         vaccine = "I-I",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse201530_I_I_D1, file = "gse201530_I_I_D1_DEGs-PF.csv")


#D3
gse201530_I_I_D3 = results(dds, contrast = c("disease_time", "I.I_D3", "H_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "I-I (D3)",
         day = 3,
         vaccine = "I-I",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse201530_I_I_D3, file = "gse201530_I_I_D3_DEGs-PF.csv")


#D5
gse201530_I_I_D5 = results(dds, contrast = c("disease_time", "I.I_D5", "H_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "I-I (D5)",
         day = 5,
         vaccine = "I-I",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse201530_I_I_D5, file = "gse201530_I_I_D5_DEGs-PF.csv")

gse201530_I_I = bind_rows(gse201530_I_I_D1,
                          gse201530_I_I_D3,
                          gse201530_I_I_D5)

Unir raw datasets

########## GSE201530

gse201530_DEGs = bind_rows(gse201530_I_I,
                           gse201530_H_I_I_D2,
                           gse201530_H_I,
                           gse201530_I_BNT_I,
                           gse201530_H_BNT_I) %>% 
  mutate(study = "GSE201530")

#Salvar
write.csv(gse201530_DEGs, file = "gse201530_DEGs_27-11-23.csv")

GSE201530_metadata_conditions = gse201530_DEGs %>% 
  select(condition:vaccine, study) %>% 
  distinct()


#Anotações
ann_vaccines_lower = ann_vaccines %>% 
  clean_names()

ann_vaccines_27_11_23 = bind_rows(ann_vaccines_lower, 
                                  GSE201530_metadata_conditions)

#Salvar
write.csv(ann_vaccines_27_11_23, file = 'ann_vaccines_27_11_23.csv')

GSE189039

Comparando tempos e condições

Nesta comparação, são encontradas DEGs de cada vacina individual nos diferentes tempos. Para comparar uma vacina com a outra em diferentes tempos, é necessário usar os argumentos “contrast” ou “name”.

H_I

######### H_I

#H_I_D10
gse189039_H_I_moderate_D10 = results(dds, contrast = c("disease_vac_severity_time", "H.I_moderate_D10", "H_naive_vac_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "H-I (D10, moderate)",
         day = 10,
         vaccine = "H-I",
         severity = "moderate",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse189039_H_I_moderate_D10, file = "gse189039_H_I_moderate_D10_DEGs.csv")

#H_I_D26
gse189039_H_I_moderate_D26 = results(dds, contrast = c("disease_vac_severity_time", "H.I_moderate_D26", "H_naive_vac_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "H-I (D26, moderate)",
         day = 26,
         severity = "moderate",
         vaccine = "H-I",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse189039_H_I_moderate_D26, file = "gse189039_H_I_moderate_D26_DEGs.csv")

#H_I_D51
gse189039_H_I_moderate_D51 = results(dds, contrast = c("disease_vac_severity_time", "H.I_moderate_D51", "H_naive_vac_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "H-I (D51, moderate)",
         day = 51,
         vaccine = "H-I",
         severity = "moderate",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse189039_H_I_moderate_D51, file = "gse189039_H_I_moderate_D51_DEGs.csv")

#H_I_severe_D10
gse189039_H_I_severe_D10 = results(dds, contrast = c("disease_vac_severity_time", "H.I_severe_D10", "H_naive_vac_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "H-I (D10, severe)",
         day = 10,
         vaccine = "H-I",
         severity = "severe",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse189039_H_I_severe_D10, file = "gse189039_H_I_severe_D10_DEGs.csv")



#H_I_severe_D26
gse189039_H_I_severe_D26 = results(dds, contrast = c("disease_vac_severity_time", "H.I_severe_D26", "H_naive_vac_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "H-I (D26, severe)",
         day = 26,
         vaccine = "H-I",
         severity = "severe",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse189039_H_I_severe_D26, file = "gse189039_H_I_severe_D26_DEGs.csv")

#H_I_severe_D51
gse189039_H_I_severe_D51 = results(dds, contrast = c("disease_vac_severity_time", "H.I_severe_D51", "H_naive_vac_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "H-I (D51, severe)",
         day = 51,
         vaccine = "H-I",
         severity = "severe",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse189039_H_I_severe_D51, file = "gse189039_H_I_severe_D51_DEGs.csv")

gse189039_H_I = bind_rows(gse189039_H_I_moderate_D10,
                          gse189039_H_I_severe_D10,
                            gse189039_H_I_moderate_D26,
                          gse189039_H_I_severe_D26,
                            gse189039_H_I_moderate_D51,
                          gse189039_H_I_severe_D51)

write.csv(gse189039_H_I, "gse189039_H_I_DEGS.csv")

H_BNT_I

######### H-BNT-I

#H_BNT-I

#MILD
gse189039_H_BNT_I_mild_D10 = results(dds, contrast = c("disease_vac_severity_time", "H.BNT.I_mild_D10", "H_naive_vac_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "H-BNT-I (D10, mild)",
         day = 10,
         vaccine = "H-BNT-I",
         severity = "mild",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse189039_H_BNT_I_mild_D10, file = "gse189039_H_BNT_I_mild_D10_DEGs.csv")


gse189039_H_BNT_I_mild_D26 = results(dds, contrast = c("disease_vac_severity_time", "H.BNT.I_mild_D26", "H_naive_vac_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "H-BNT-I (D26, mild)",
         day = 26,
         vaccine = "H-BNT-I",
         severity = "mild",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse189039_H_BNT_I_mild_D26, file = "gse189039_H_BNT_I_mild_D26_DEGs.csv")


#SEVERE

gse189039_H_BNT_I_severe_D10 = results(dds, contrast = c("disease_vac_severity_time", "H.BNT.I_severe_D10", "H_naive_vac_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "H-BNT-I (D10, severe)",
         day = 10,
         vaccine = "H-BNT-I",
         severity = "severe",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse189039_H_BNT_I_severe_D10, file = "gse189039_H_BNT_I_severe_D10_DEGs.csv")


gse189039_H_BNT_I_severe_D26 = results(dds, contrast = c("disease_vac_severity_time", "H.BNT.I_severe_D26", "H_naive_vac_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "H-BNT-I (D26, severe)",
         day = 26,
         vaccine = "H-BNT-I",
         severity = "severe",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse189039_H_BNT_I_severe_D26, file = "gse189039_H_BNT_I_severe_D26_DEGs.csv")

#UNIR
gse189039_H_BNT_I = bind_rows(gse189039_H_BNT_I_mild_D10,
                              gse189039_H_BNT_I_severe_D10,
                              gse189039_H_BNT_I_mild_D26,
                              gse189039_H_BNT_I_severe_D26)
#Salvar
write.csv(gse189039_H_BNT_I, file = "gse189039_H_BNT_I_DEGS.csv")

BNT-I-BNT

######### BNT-I-BNT 

# D51
gse189039_BNT_I_BNT_severe_D51 = results(dds, contrast = c("disease_vac_severity_time",
                                                         "BNT.I.BNT_severe_D51", 
                                                         "H_naive_vac_D0")) %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  arrange(padj) %>% 
  mutate(condition = "BNT-I-BNT (D51, severe)",
         day = 51,
         vaccine = "BNT-I-BNT",
         severity = "severe",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes")

#Salvar tabela
write.csv(gse189039_BNT_I_BNT_severe_D51, file = "gse189039_BNT_I_BNT_severe_D51_DEGs.csv")


#Aqui tive de usar o argumento name, pois contrast não estava funcionando (?)
gse189039_BNT_I_BNT_mild_D51 = results(dds, name= "disease_vac_severity_time_H_naive_vac_D0_vs_BNT.I.BNT_mild_D51") %>% 
  as.data.frame() %>% 
  filter(padj < 0.05) %>%
  mutate(log2FoldChange = ifelse(log2FoldChange > 0, -log2FoldChange, abs(log2FoldChange))) %>% 
  arrange(padj) %>% 
  mutate(condition = "BNT-I-BNT (D51, mild)",
         day = 51,
         vaccine = "BNT-I-BNT",
         severity = "mild",
         direction = ifelse(log2FoldChange >= 1, "UP", 
                            ifelse(log2FoldChange <= -1, "DOWN", 
                                   "NEUTRAL")))  %>% 
  rownames_to_column("genes") 

#Salvar tabela
write.csv(gse189039_BNT_I_BNT_mild_D51, file = "gse189039_BNT_I_BNT_mild_D51_DEGs.csv")

#Unir
gse189039_BNT_I_BNT = bind_rows(gse189039_BNT_I_BNT_mild_D51,
                                gse189039_BNT_I_BNT_severe_D51)


write.csv(gse189039_BNT_I_BNT, file = "gse189039_BNT_I_BNT_DEGS.csv")

UNIR

all_degs_p_05_vac_infected = bind_rows(degs_allstudies_updown_p_05,
                                       gse_201530_189039) %>% 
  mutate_all(~ replace(., is.na(.), "NA")) %>% 
  mutate(regimen = case_when(
regimen == "BNT-I-BNT" ~ "V-I-V",
regimen == "H-BNT-I" ~ "V-I",
regimen == "VAC-I" ~ "V-I",
regimen == "I-VAC-I" ~ "I-V-I",
regimen == "H-V-I" ~ "V-I",
regimen == "H-I-I" ~ "I-I",
regimen == "H-I" ~ "I",
TRUE ~ as.character(regimen)))
Error: object 'degs_allstudies_updown_p_05' not found

Comparar numero de participantes

Comparar sexo

Combinar tabela de genes sequenciados (raw)

genes_raw_combined %>% 
  group_by(study) %>% 
  summarise(study, 
            n_genes = n()) %>% 
  distinct()
Warning: Returning more (or less) than 1 row per `summarise()` group was deprecated in dplyr 1.1.0.
Please use `reframe()` instead.
When switching from `summarise()` to `reframe()`, remember that `reframe()` always returns an ungrouped data frame and adjust accordingly.`summarise()` has grouped output by 'study'. You can override using the `.groups` argument.

5. Visualização de dados

DEGs plot

5.1. Volcanoplot

Os volcanoplots das duas vacinas são os mesmos, mas espelhados. Isso significa que definir o nivel de referencia no fator de vacinas é importante para determinar as DEGs up e down. #### ASTRAZENECA

Astrazeneca


#All
volcano_res <- EnhancedVolcano(res, 
                                    lab = rownames(res),
                                    x = 'log2FoldChange',
                                    y = 'pvalue',
                                    title='Differential expression of genes - All timepoints - ChAdOx1')
# Save the plot as a PNG file
png("gse199750_volcanoplot_DEGs_allfactores_AZ.png", width = 800, height = 600)
print(volcano_res_chad)
dev.off()

#T1-T0
volcano_res_chad_1_0 <- EnhancedVolcano(res_1_0_chad, 
                                    lab = rownames(res_1_0_chad),
                                    x = 'log2FoldChange',
                                    y = 'pvalue',
                                    title='Differential expression of genes - D1 vs. D0 - ChAdOx1')
# Save the plot as a PNG file
png("gse199750_volcanoplot_DEGs_D0-D1_AZ.png", width = 800, height = 600)
print(volcano_res_chad_1_0)
dev.off()

#T2-T0
volcano_res_chad_2_0 <- EnhancedVolcano(res_time0_time2_chad, 
                                    lab = rownames(res_time0_time2_chad),
                                    x = 'log2FoldChange',
                                    y = 'pvalue',
                                    title='Differential expression of genes - D2 vs. D0 - ChAdOx1')
# Save the plot as a PNG file
png("gse199750_volcanoplot_DEGs_D0-D2_AZ.png", width = 800, height = 600)
print(volcano_res_chad_2_0)
dev.off()

#Plotar mais de um gráfico
plot_grid(volcano_res_chad, volcano_res_chad_1_0, volcano_res_chad_2_0, ncol = 3) 

5.2. Heatmap

5.3. Diagrama de Venn com Heatmap

Tabela de overlaps de DEGs com teste exato de fisher

Determinar a proporção de DEGs compartilhadas entre condições diferentes e sua significância. O código abaixo deve ter como input uma tabela longa chamada “degs_all” (coluna 1: condicoes/vacinas, coluna 2: DEGs). O output será uma tabela longa com as colunas Vacina 1, Vacina 2, shared degs, not shared vacina 1, not shared vacina 2, lista com nomes das degs, valor p de fisher (teste exato de fisher).

pHeatmap

#Salvar imagem
png(file= paste0("shared", filename, "_p<10_qvalue10_PHEATMAP_numbers.png"), 
    width=3000, 
    height=2000, 
    res=315, 
    pointsize=10)
print(pheatmap_shared)
dev.off()
null device 
          1 
#Salvar imagem
png(file= paste0("shared", filename, "_p<10_qvalue10_PHEATMAP_nonumbers.png"), 
    width=3000, 
    height=2000, 
    res=315, 
    pointsize=10)
print(pheatmap_shared_nonumbers)
dev.off()
null device 
          1 

Chord diagram

#Chord diagram
install.packages("circlize")
library(circlize)

# sharedDEGs_UPDOWN_fisher_pvalue10
# sharedDEGs_UP_fisher_p_10_pvalue10
# sharedDEGs_DOWN_fisher_p_10_pvalue10

#Input
shared_genes_df_mirror_p10 = sharedDEGs_UP_fisher_p_10_pvalue10


#All doses
circos_alldoses = shared_genes_df_mirror_p10 %>% 
  select(Cond1, Cond2, Shared) %>% 
  mutate(Shared = as.numeric(Shared)) %>%  
  merge(ann_vaccines, by.x = "Cond1", by.y="Condition", all.x=T, all.y=F) %>%
  merge(ann_vaccines, by.x = "Cond2", by.y="Condition", all.x=T, all.y=F) %>% 
  select(Cond1, Cond2, Shared,Dose.x, Dose.y) %>% 
  rename(cond1_dose = Dose.x,
         cond2_dose = Dose.y) %>% 
  filter(Shared != 0)

circos_alldoses_mirror = circos_alldoses %>% 
  mutate(Cond1A = Cond2,
         Cond2A = Cond1) %>% 
  select(Cond1A, Cond2A, Shared, cond1_dose, cond2_dose) %>% 
  rename(Cond1 = Cond1A,
         Cond2 = Cond2A) %>% 
  rbind(circos_alldoses)

write.csv(circos_alldoses_mirror, file = "Circos_DOWN_Alldoses_pvalue10_dose1.csv")


#Dose 1
circos_dose1 = shared_genes_df_mirror_p10 %>% 
  select(Cond1, Cond2, Shared) %>% 
  mutate(Shared = as.numeric(Shared)) %>%  
  merge(ann_vaccines, by.x = "Cond1", by.y="Condition", all.x=T, all.y=F) %>%
  merge(ann_vaccines, by.x = "Cond2", by.y="Condition", all.x=T, all.y=F) %>% 
  select(Cond1, Cond2, Shared,Dose.x, Dose.y) %>% 
  rename(cond1_dose = Dose.x,
         cond2_dose = Dose.y) %>% 
  filter(cond1_dose == 1,
         cond2_dose == 1)

circos_dose1_mirror = circos_dose1 %>% 
  mutate(Cond1A = Cond2,
         Cond2A = Cond1) %>% 
  select(Cond1A, Cond2A, Shared, cond1_dose, cond2_dose) %>% 
  rename(Cond1 = Cond1A,
         Cond2 = Cond2A) %>% 
  rbind(circos_dose1)

write.csv(circos_dose1_mirror, file = "Circos_DOWN_pvalue10_dose1.csv")

#Dose 2
circos_dose2 = shared_genes_df_mirror_p10 %>% 
  select(Cond1, Cond2, Shared) %>% 
  mutate(Shared = as.numeric(Shared)) %>%  
  merge(ann_vaccines, by.x = "Cond1", by.y="Condition", all.x=T, all.y=F) %>%
  merge(ann_vaccines, by.x = "Cond2", by.y="Condition", all.x=T, all.y=F) %>% 
  select(Cond1, Cond2, Shared,Dose.x, Dose.y) %>% 
  rename(cond1_dose = Dose.x,
         cond2_dose = Dose.y) %>% 
  filter(cond1_dose == 2,
         cond2_dose == 2)
circos_dose2_mirror = circos_dose2 %>% 
  mutate(Cond1A = Cond2,
         Cond2A = Cond1) %>% 
  select(Cond1A, Cond2A, Shared, cond1_dose, cond2_dose) %>% 
  rename(Cond1 = Cond1A,
         Cond2 = Cond2A) %>% 
  rbind(circos_dose2) 

write.csv(circos_dose2_mirror, file = "Circos_DOWN_pvalue10_dose2.csv")

#Dose 3
circos_dose3 = shared_genes_df_mirror_p10 %>% 
  select(Cond1, Cond2, Shared) %>% 
  mutate(Shared = as.numeric(Shared)) %>%  
  merge(ann_vaccines, by.x = "Cond1", by.y="Condition", all.x=T, all.y=F) %>%
  merge(ann_vaccines, by.x = "Cond2", by.y="Condition", all.x=T, all.y=F) %>% 
  select(Cond1, Cond2, Shared,Dose.x, Dose.y) %>% 
  rename(cond1_dose = Dose.x,
         cond2_dose = Dose.y) %>% 
  filter(cond1_dose == 3,
         cond2_dose == 3)

 circos_dose3_mirror = circos_dose3 %>% 
  mutate(Cond1A = Cond2,
         Cond2A = Cond1) %>% 
  select(Cond1A, Cond2A, Shared, cond1_dose, cond2_dose) %>% 
  rename(Cond1 = Cond1A,
         Cond2 = Cond2A) %>% 
  rbind(circos_dose3) 

write.csv(circos_dose3_mirror, file = "Circos_DOWN_pvalue10_dose3.csv")

Visualização

Dotplot

#### Identidade e -log(q)
install.packages("ggdendro")
library(ggdendro)
library(cowplot)
library(ggtree)
library(patchwork) 

#Filtrar valores com -log(p) >= 1
sharedDEGs_UP_DOWN_fisher_filtered <- sharedDEGs_UP_DOWN_fisher %>%
  mutate(`Significance -log(p)` = cut(`-log(p)`, 
                        breaks = c(-Inf, 1, 1.3, 2, Inf), 
                        labels = c("<1", "1-1.3", "1.3-2", ">2"))) %>%
  filter(Percentage_Shared_Cond1 >= 1, Percentage_Shared_Cond2 >= 1, `Significance -log(p)` != "<1")

#Salvar
write.csv(sharedDEGs_UP_DOWN_fisher_filtered, file = "sharedDEGs_UP_DOWN_fisher_filtered.csv")

#Visualizar
plot = ggplot(sharedDEGs_UP_DOWN_fisher, aes(x = Cond1, y = Cond2, color = Percentage_Shared_Cond1, size = Percentage_Shared_Cond1)) + 
  geom_point() +
  scale_size_continuous(range = c(2, 8)) +
  geom_text(aes(label = sprintf("%.f", Percentage_Shared_Cond1)), vjust = 0.5, hjust = 0.5, size = 2, color = "black")  +
  cowplot::theme_cowplot() + 
  theme(axis.line = element_blank(),
        axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1, size = 10),
        axis.text.y = element_text(size = 10)) +
  scale_color_gradient(low = "white", high = "#ef233c", limits = c(0, 60)) +
  ggtitle("%Identity between vaccines, Up and Down-Regulated, pvalue < 0.05" ) +
  ylab('Cond2') +
  theme(axis.ticks = element_blank()) +
  guides(color = FALSE, size = FALSE)

#Salvar
ggsave(plot, file = "sharedDEGs_UP_DOWN_fisher.png")

#Display
plot

Single Sample GSEA (ssGSEA)

ImmuneGO

library(corto)
############## Arquivos necessários

#CellMarker_ImmuneCells.csv 
#ImmuneGO_Annotated_Genes_Nested_Interesting.csv
ann_vaccines #Anotação das vacinas

############## GSE199750
gse199750_metadata_annotated    = gse199750_metadata_annotated_16_11_23 %>% 
  mutate(condition = case_when(
    condition == "BNT (V1, D6)BNT" ~ "BNT (V1, D6)",
    condition == "BNT (V1, D6)MO" ~ "BNT-MO (V1, D6)",
    TRUE ~ condition)) %>% 
  select(sample, condition, geo, day, dose, age, sex)

#Salvar
write.csv(gse199750_metadata_annotated, file = "gse199750_metadata_annotated_22-11-23.csv")

gse199750_counts_ready #matriz de expressão


############## GSE201533

gse201533_metadata_annotated = gse201533_metadata_long_annotated_14_11_23 %>% #Metadados
  select(condition:vaccine)

gse201533_counts_ready #Matriz de expressão


############## GSE206023
gse206023_metadata_ready = gse206023_counts_long_annotated_14_11_23 %>%  #Metadados
  select(condition:age) %>% 
  distinct() %>% 
  mutate(type = if_else(type=="HO", "IN", type))

write.csv(gse206023_metadata_ready, file = "gse206023_metadata_ready.csv")

#Matriz de expressão
gse206023_counts_ready = gse206023_counts_long_annotated_14_11_23 %>% 
  mutate(counts = as.numeric(counts)) %>% 
  select(genes, sample, counts) %>% 
  pivot_wider(names_from = sample, values_from = counts, values_fn = mean) %>% 
  column_to_rownames("genes")

write.csv(gse206023_counts_ready, file = "gse206023_counts_ready.rds")
############## Inputs

ssgsea_gene = gse206023_counts_ready #Criar variável
metadata = gse206023_metadata_ready
filename = "GSE206023"
go_dataset = "CellMarker"

#Extrair sample names. O ssGSEA perde o nome no resultado.
sample_names = ssgsea_gene %>% 
  as.data.frame() %>% 
  colnames() %>% 
  as.data.frame() %>% 
  rename(sample_names = '.')

#Tabela com genes de interesse (geral) convertida em listas 

genelist = CellMarker_ImmuneCells %>% #CellMarker_ImmuneCells.csv
  select(cell = cell_name, genes = marker)
genelist = split(genelist$genes, genelist$cell) 

############## Análise 

# Run ssGSEA
nesmat = ssgsea(ssgsea_gene, genelist)

#Padronizar resultado
nesmat.result = nesmat %>% 
  as.data.frame() %>% 
  t() %>% 
  as.data.frame() %>% 
  rownames_to_column("sample") %>% 
  relocate(sample, .before = everything()) %>% 
  cbind(sample_names) %>% 
  select(-sample) %>% 
  column_to_rownames("sample_names") %>% 
  t() %>% 
  as.data.frame() %>% 
  rownames_to_column("process") %>% 
  relocate(process, .before=everything()) %>% 
  pivot_longer(cols = -process, names_to = "sample", values_to = "nes") %>% 
  mutate(pvalue = z2p(nes), #Converter NES em pvalue
         qvalue = p.adjust(pvalue, method = "BH"), #ajustar para qvalue 
         logq = - log10(qvalue)) %>%  #Calcular -log(q)
  merge(metadata, by="sample", all.x=T) %>% #Unir com metadata
  mutate(study = filename) %>% 
  merge(CellMarker_ImmuneCells, by.x ="process", by.y = "cell_name", all.x=T) %>% 
  select(-"...1") %>% 
  rename(cell_name = process)

#Salvar
write.csv(nesmat.result, file = paste0(filename, sep = "_", go_dataset, "_ssgsea_result.csv"))

print(nesmat.result)

Unir resultados


############### Unir resultados
GSE199750_CellMarker_ssgsea_result = GSE199750_CellMarker_ssgsea_result %>%
  clean_names() %>% 
  select(cell_name:type, -marker) %>% 
  distinct()

GSE201533_CellMarker_ssgsea_result = GSE201533_CellMarker_ssgsea_result %>% 
  clean_names() %>% 
  select(cell_name:type, -marker) %>% 
  distinct()

GSE206023_CellMarker_ssgsea_result = GSE206023_CellMarker_ssgsea_result %>% 
  clean_names() %>% 
  select(cell_name:type, -marker) %>% 
  distinct() 
  
  
GSE206023_CellMarker_ssgsea_result = GSE206023_CellMarker_ssgsea_result %>% 
  mutate(age = as.double(age))

ssgsea_results_unified = bind_rows(GSE199750_CellMarker_ssgsea_result,
          GSE201533_CellMarker_ssgsea_result,
          GSE206023_CellMarker_ssgsea_result)

ssgsea_results_unified = ssgsea_results_unified %>% 
  select(cell_name:immune_system) %>% 
  merge(ann_vaccines, by.x = "condition", by.y = "Condition")

#Salvar
write.csv(ssgsea_results_unified, file = paste0(go_dataset, "_ssgsea_results_unified.csv"))

Visualização


# INPUT
nesmat.result = GSE199750_ssgsea_result
filename = "GSE199750"

#Filtrar

#Lista de processos

ssgsea_interesting = nesmat.result %>% 
  filter(pvalue <= 0.10) %>% 
  distinct()

#Boxplot (NES)
NES_plot = ggplot(ssgsea_interesting) +
  aes(x = condition, y = nes, fill = vaccine) +
  geom_boxplot() +
  scale_fill_hue(direction = 1) +
  theme_minimal() +
  facet_grid(vars(process), vars(vaccine), scales = "free_x") +
 labs(title = paste0(filename, "_ImmuneGO ssGSEA"), 
      fill = "vaccine") +
 theme_bw() +
 theme(plot.title = element_text(size = 20L, face = "bold", hjust = 0.5),
       axis.text.x = element_text(angle = 45, vjust = 1, hjust=1, size = 7)) 

#Salvar
ggsave(NES_plot, file= paste0(filename, "_ssGSEA_NES_qvalue010.png"), width = 10, height = 20)
ssgsea_interesting.unified = ssgsea_results_unified %>% 
  filter(!condition %in% c("BNT-MO (V1, D0)", "BNT-MO (V2, D0)")) %>% 
  mutate(day = as.factor(day),
         dose = as.factor(dose))

ssgsea_interesting.general.unified = ssgsea_interesting.unified %>% 
  filter(process %in% c("ADAPTIVE IMMUNE SYSTEM", 
                        "CELLULAR ADAPTIVE IMMUNE SYSTEM", 
                        "INNATE IMMUNE SYSTEM", 
                        "INFLAMMATION"),
         pvalue <= 0.10)

ssgsea_interesting.specific.unified = ssgsea_interesting.unified %>% 
  filter(!process %in% c("ADAPTIVE IMMUNE SYSTEM", 
                         "CELLULAR ADAPTIVE IMMUNE SYSTEM", 
                         "INNATE IMMUNE SYSTEM", 
                         "INFLAMMATION"),
         pvalue <= 0.10)


data = ssgsea_results_unified
filename.unified = "ssgsea_results_unified"
#All conditions divided by dose, time on x-axis

# Filtrar os dados antes de passar para ggplot
filtered_data <- data %>%
  group_by(cell_name, Vaccine, condition) %>%
  summarise(n = n()) %>%
  filter(n < 5) %>%
  pull(condition)


NES_plot_unified_dayx <- ggplot(data) +
  aes(x = day, y = nes, fill = Vaccine) +
  geom_boxplot(outlier.alpha = 1) +
  geom_point(data = subset(data, day %in% filtered_data),
             aes(x = day, y = nes, color = Vaccine),
             position = position_jitter(width = 0.2), alpha = 1) +
  scale_fill_manual(values = vaxcolors) +
  scale_color_manual(values = c(BBIBP = "#ffd000", 
                                ZF2001 = "#b5179e",
                                BNT = "#56cfe1",
                                ChAd = "#80ffdb" ,
                                "ChAd-BNT" = "#72efdd")) +
  labs(
    title = "ssGSEA - All studies",
    subtitle = "General ImmuneGO, by dose",
    caption = "Vaccine",
    fill = "Vaccines"
  ) + 
  theme_minimal() +
  facet_grid(vars(Type), vars(dose), scales = "free_x") +
  theme(plot.title = element_text(size = 20L, face = "bold", hjust = 0.5),
        strip.text.y = element_text(angle = 0, vjust = 1, hjust = 1, size = 5),
        strip.text.x = element_text(size = 10))

#Salvar
ggsave(NES_plot_unified_dayx, file = paste0(filename.unified, "_ssGSEA_NES_qvalue010_2.png"), width = 10, height = 10)

print(NES_plot_unified_dayx)
#All conditions divided by vaccine, time on x-axis

# Criar o gráfico
NES_plot_unified_dayx_vax <- ggplot(data) +
  aes(x = condition, y = nes, fill = dose) +
  geom_boxplot(outlier.alpha = 0.5) +
  geom_point(data = subset(data, condition %in% filtered_data),
             aes(x = condition, y = nes, color = "black"),
             position = position_jitter(width = 0.2), alpha = 1) +
  scale_fill_manual(values = dose_colors) +
  scale_color_manual(values = dose_colors) +
  labs(
    title = "ssGSEA - All studies",
    subtitle = "General ImmuneGO, by dose",
    caption = "Vaccine",
    fill = "Vaccines"
  ) +
  theme_minimal() +
  facet_grid(vars(process), vars(vaccine), scales = "free") +
  theme(
    plot.title = element_text(size = 20L, face = "bold", hjust = 0.5),
    axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1, size = 7),
    strip.text.y = element_text(angle = 0, vjust = 1, hjust = 1, size = 7)  # Rotação do texto da facet row
  )

#Salvar
ggsave(NES_plot_unified_dayx_vax, file = paste0(filename.unified, "_ssGSEA_NES_qvalue010_3.png"), width = 20, height = 20)

print(NES_plot_unified_dayx_vax)

Analise estatística

install.packages("ggstatsplot")
library(ggstatsplot)

ssgsea_interesting = ssgsea_interesting %>% 
  filter(process == "INNATE IMMUNE SYSTEM") %>% 
  distinct()

process = "INNATE IMMUNE SYSTEM"


ggbetweenstats(
  data  = ssgsea_interesting,
  x     = condition,
  y     = nes,
  title =  paste0("ImmuneGO ssGSEA ", filename, process)
)

#Agrupado
grouped_ggbetweenstats(
  data             = ssgsea_interesting,
  x                = condition,
  y                = nes,
  grouping.var     = process,
  ggsignif.args    = list(textsize = 4, tip_length = 0.01),
  p.adjust.method  = "bonferroni",
  palette          = "default_jama",
  package          = "ggsci",
  plotgrid.args    = list(nrow = 1),
  annotation.args  = list(title = paste0("ImmuneGO ssGSEA ", filename))
)

ANOVA

esquisser(test)

library(ggsignif)
library(rstatix)

df = test
df$Condition <- as.factor(df$Condition)

stat.test <- df %>%
  t_test(Condition ~ NES) %>%
  add_significance()


test %>%
  filter(Process %in% "INNATE IMMUNE RESPONSE") %>%
  ggboxplot(x = "Process", y = "NES",
          color = "Condition", palette = "jco") +
  facet_wrap(vars(Vaccine)) +
  stat_compare_means(method = "anova", label.y = 4) +      # Add global p-value
  stat_compare_means(label = "p.signif", method = "t.test",
                     ref.group = ".all.")    # Comparação múltipla usando Tukey HSD


# Box plots with p-values
bxp <- ggboxplot(df, x = "Process", y = "NES", fill = "#00AFBB")
stat.test <- stat.test %>% add_xy_position(x = "supp")
bxp + 
  stat_pvalue_manual(stat.test, label = "p") +
  scale_y_continuous(expand = expansion(mult = c(0.05, 0.1)))

PCA

https://www.datacamp.com/tutorial/pca-analysis-r https://rpkgs.datanovia.com/factoextra/index.html http://www.sthda.com/english/articles/31-principal-component-methods-in-r-practical-guide/114-mca-multiple-correspondence-analysis-in-r-essentials/ https://statisticsglobe.com/pca-before-k-means-clustering-r>

Bibliotecas

library(factoextra)
library(caret)
library(stats)
library(ggfortify)
library(ggplot2)

By GO term


ssgsea_results_unified = ssgsea_results_unified %>% distinct() 
  
ssgsea_results_unified.innate = ssgsea_results_unified %>% 
  filter(process %in% c("INNATE IMMUNE SYSTEM", "ANTIVIRAL AND INTERFERON", "ARPP", "INFLAMMATION", "DENDRITIC CELLS", "MACROPHAGES"))

ssgsea_results_unified.adaptive = ssgsea_results_unified %>% 
  filter(!process %in% c("INNATE IMMUNE SYSTEM", "ANTIVIRAL AND INTERFERON", "ARPP", "INFLAMMATION", "DENDRITIC CELLS", "MACROPHAGES")) %>% 
  filter(!study == "GSE201533")
  
data_ImmuneGO = ssgsea_results_unified.adaptive 
filename = "ssgsea_results_unified.adaptive"

pca_ann = data_ImmuneGO %>% 
  select(sample, condition, vaccine, geo:sex)

#Converter de long para wide
matrix_genes = data_ImmuneGO %>% 
  select(sample, process, nes)

matrix_genes <- dcast(matrix_genes, `sample` ~ `process`, 
                     value.var = "nes", 
                     fun.aggregate = mean)

matrix_genes <- replace(matrix_genes, matrix_genes == "NaN", 0) 

#Converter coluna 1 em rownames e excluir
matrix_data_pca = matrix_genes %>% 
  as.data.frame()

matrix_data_pca_ready = matrix_data_pca %>%  
  column_to_rownames("sample")

ann_vaccines_pca_matrix = matrix_data_pca %>% 
  merge(pca_ann, by.y = "sample", by.x = "sample", all.x = T, all.y = F) %>% 
  distinct()

ann_vaccines_pca_matrix_ready = ann_vaccines_pca_matrix %>% 
  select(sample, condition, vaccine, day, dose) %>% 
  mutate(dose = as.factor(dose),
         day = as.factor(day))

# Verifique quais colunas têm variância muito baixa
nearZeroVarCols <- nearZeroVar(matrix_data_pca_ready, saveMetrics = TRUE)
matrix_data_pca_ready <- matrix_data_pca_ready[, !nearZeroVarCols$nzv]
pca_res <- prcomp(matrix_data_pca_ready, scale. = TRUE)

# Crie o gráfico de PCA

###### Condition
pca_plot_condition = autoplot(pca_res, 
                    data = ann_vaccines_pca_matrix_ready, 
                    colour = 'condition', 
                    label = 0) + 
  labs(title=paste0(filename, "_bycondition")) + #scale fill manual
  scale_fill_continuous(type = "viridis") +
  theme_minimal()


###### Vaccine
pca_plot_vac = autoplot(pca_res, 
                    data = ann_vaccines_pca_matrix_ready, 
                    colour = 'vaccine', 
                    label = 0) + 
  labs(title=paste0(filename, "_byvaccine")) + #scale fill manual
  scale_color_manual(
    values = c(
  "BBIBP" = "#ffd000",
  "BNT" = "#56cfe1",
  "ChAd" = "#80ffdb",
  "ChAd-BNT" = "#0077b6",
  "ZF2001" = "#b5179e")) +
  theme_minimal()

###### Day
pca_plot_day = autoplot(pca_res, 
                    data = ann_vaccines_pca_matrix_ready, 
                    colour = 'day', 
                    label = 0) + 
  labs(title=paste0(filename, "_day")) + #scale fill manual
   scale_color_manual(
     values = c(
       "0" = "grey90",
    "1" = "#caf0f8",
    "3" = "#90e0ef",
    "6" = "#00b4d8",
    "7" = "#0077b6",
    "14" = "#023e8a",
    "28" = "#03045e")) +
  theme_minimal()

###### Dose

pca_plot_dose = autoplot(pca_res, 
                    data = ann_vaccines_pca_matrix_ready, 
                    colour = 'dose', 
                    label = 0) + 
  labs(title=paste0(filename, "_dose")) +
  scale_color_manual(
    values = c("0" = "#caf0f8", 
               "1" = "#56cfe1", 
               "2" = "#5978d4",
               "3" = "#b5179e"))+
  theme_minimal()

# Exiba o gráfico
print(pca_plot_condition)
print(pca_plot_day)
print(pca_plot_dose)
print(pca_plot_vac)

ggsave(pca_plot_condition, filename = paste0(filename, "CONDITION_PCA_Immune_GO_GSEA_not-ann.png"), width = 10, height = 8)
ggsave(pca_plot_vac, filename = paste0(filename, "_VACCINE_PCA_Immune_GO_GSEA_not-ann.png"), width = 10, height = 8)
ggsave(pca_plot_day, filename = paste0(filename, "_DAY_PCA_Immune_GO_GSEA_not-ann.png"), width = 10, height = 8)
ggsave(pca_plot_dose, filename = paste0(filename, "_DOSE_PCA_Immune_GO_GSEA_not-ann.png"), width = 10, height = 8)
############### KNN classification

#Determinar o número de clusters para KNN
pca_scores <- data.frame(pca_res$x[, 1:2])
fviz_nbclust(pca_scores,  
                     FUNcluster = kmeans,
                     method = "wss")

set.seed(123)                             # Set seed for randomization
kmeans_clust <- kmeans(pca_scores,        # Perform k-means clustering
                        centers = 3) # Definir numero de clusters

#Visualizar clusters
ggp2 <- fviz_pca_ind(pca_res,
                   habillage = kmeans_clust$cluster,
                   repel = TRUE,
                   addEllipses = TRUE,
                   ellipse.type = "t",
                   label = "none",
                   labelsize = 0) +
  guides(color = guide_legend(override.aes = list(label = ""))) +
  ggtitle(paste0(filename,  "_KNN_Clustered.png")) +
  scale_color_brewer(palette="Set1")

print(ggp2)

ggsave(ggp2, file = paste0(filename, "_KNN_Clustered.png"), width = 5, height = 4)


# Clusterizar por grupo

#Vaccine
pca_group_vac <- fviz_pca_ind(pca_res,
                   habillage = ann_vaccines_pca_matrix_ready$vaccine,
                   repel = TRUE,
                   addEllipses = TRUE,
                   ellipse.type = "t",
                   label = "none",
                   labelsize = 0) +
  guides(color = guide_legend(override.aes = list(label = ""))) +
  ggtitle(paste0(filename,  "_Vac_KNN_Clustered.png")) +
  scale_color_brewer(palette="Set1")

#Dose
pca_group_dose <- fviz_pca_ind(pca_res,
                   habillage = ann_vaccines_pca_matrix_ready$dose,
                   repel = TRUE,
                   addEllipses = TRUE,
                   ellipse.type = "t",
                   label = "none",
                   labelsize = 0) +
  guides(color = guide_legend(override.aes = list(label = ""))) +
  ggtitle(paste0(filename,  "_Dose_KNN_Clustered.png")) +
  scale_color_brewer(palette="Set1")

#Day
pca_group_day <- fviz_pca_ind(pca_res,
                   habillage = ann_vaccines_pca_matrix_ready$day,
                   repel = TRUE,
                   addEllipses = TRUE,
                   ellipse.type = "t",
                   label = "none",
                   labelsize = 0) +
  guides(color = guide_legend(override.aes = list(label = ""))) +
  ggtitle(paste0(filename,  "_Day_KNN_Clustered.png")) +
  scale_color_brewer(palette="Set1")


#Salvar
ggsave(pca_group_day, file = paste0(filename, "_Day_Clustered.png"), width = 5, height = 4)
ggsave(pca_group_dose, file = paste0(filename, "_Dose_Clustered.png"), width = 5, height = 4)
ggsave(pca_group_vac, file = paste0(filename, "_Vac_Clustered.png"), width = 5, height = 4)
#Biplot
biplot = fviz_pca_biplot(pca_res,              # Visualize clusters in biplot
                      col.var = "black",
                      alpha.var = 0.5,
                      habillage = kmeans_clust$cluster,
                      repel = TRUE,
                      addEllipses = TRUE,
                      ellipse.type = "convex",
                      labelsize = 3,
                      label = "var",
                      palette = "Set1")


ggsave(biplot, file = paste0(filename, "_BIPLOT_KNN_Clustered.png"), width = 10, height = 8)
########Correlation plot
corr_matrix = cor(matrix_data_pca_ready) 

#Plot
corrplot = ggcorrplot(corr_matrix, hc.order = TRUE) + 
  theme(axis.text.x = element_text(angle = 90, size = 5), 
        axis.text.y = element_text(size = 5))
#Salvar
ggsave(corrplot, file = paste0(filename, "_corrplot.png"), 
       width = 4, #Grande 20, pequeno 10
       height= 4) #Grande 20, pequeno 10
print(corrplot)
data.pca <- princomp(corr_matrix) #PCA
summary(data.pca) #Retornar PCs


#########Scree plot
data.pca = princomp(corr_matrix) #PCA
summary(data.pca) #Retornar PCs

#########Scree plot
scree_plot = fviz_eig(data.pca, 
                      addlabels = TRUE,
                      ylim = c(0, 70)) +
  geom_col(color = "#00AFBB", fill = "#00AFBB") +
  theme_classic()

#Salvar
ggsave(scree_plot, file = paste0(filename, "_GSEA_screeplot.png"), width = 10, height = 3) 
print(scree_plot)


#Scree plot
loadings = data.frame(data.pca$loadings[, 1:3])
loadings$Genes = rownames(loadings)
loadings_1 = arrange(loadings, desc(Comp.1))
loadings_2 = arrange(loadings, desc(Comp.2))
loadings_3 = arrange(loadings, desc(Comp.3))

#Plot
loadings_1_plot = ggplot(loadings_1, aes(x = reorder(Genes, -Comp.1), y=Comp.1, fill = Comp.1)) + 
  ggtitle(paste0("Comp1-Comp2 Genes", filename)) + 
  ylab("Comp1") +
  xlab("Gene sets") +
  geom_bar(stat = "identity") + 
  theme_light() +
  theme(axis.text.x = element_text(vjust = 1, hjust = 1, angle = 45, size = 8), 
        axis.text.y = element_text(size = 5),
        plot.title = element_text(size = 15L, hjust = 0.5)) + 
  scale_fill_continuous(type = "viridis") #cores

print(loadings_1_plot)


loadings_2_plot = ggplot(loadings_2, aes(x = reorder(Genes, -Comp.2), y=Comp.2, fill = Comp.2)) + 
  ggtitle(paste0("Comp2-Comp3 Genes_", filename)) + 
  ylab("Comp2") +
  xlab("Gene sets") +
  geom_bar(stat = "identity") + 
  theme_light() +
  theme(axis.text.x = element_text(vjust = 1, hjust = 1, angle = 45, size = 8), 
        axis.text.y = element_text(size = 5),
        plot.title = element_text(size = 15L, hjust = 0.5)) + 
  scale_fill_continuous(type = "viridis") #cores

print(loadings_2_plot)


#Salvar
ggsave(loadings_1_plot, 
       file = paste0(filename, "_GSEA_genescomp1-2.png"), 
       width = 10, height = 5)

#Salvar
ggsave(loadings_2_plot, 
       file = paste0(filename, "_GSEA_genescomp2-3.png"), 
       width = 10, height = 5)


# Graph of the variables
fviz_pca_var_genes = fviz_pca_var(data.pca, 
                                  col.ind = "cos2",
                                  gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"))
fviz_pca_var_genes

ggsave(fviz_pca_var_genes, file = paste0(filename, "_fviz_pca_var_GSEA.png"), width = 10)

cos2.1 = fviz_cos2(data.pca, choice = "var", axes = 1:2)
cos2.2 = fviz_cos2(data.pca, choice = "var", axes = 2:3)

ggsave(cos2.1, file = paste0(filename, "_cos2_GSEA_1.png"), width = 10)
ggsave(cos2.2, file = paste0(filename, "_cos2_GSEA_2.png"), width = 10)

By genes

Processar dados

# Immune_GO_general_innate
# Immune_GO_adaptive

#INPUT
data_genes = ssgsea_results_unified
filename = "ssgsea_results_unified"

PCA

#Converter de long para wide
matrix_genes = data_genes %>% 
  select(study, genes, l2fc) %>%  
  dcast(`study` ~ `genes`, 
        value.var = "l2fc", 
        fun.aggregate = mean) %>% 
  as.data.frame() %>% 
  column_to_rownames(var = "study") %>% 
  replace(is.na(.), 0)

matrix_data_pca = matrix_genes %>% 
  rownames_to_column(var = "Condition")

matrix_data_pca_ready = matrix_data_pca %>% 
  column_to_rownames(var = "Condition")

ann_vaccines_pca_matrix = ann_vaccines_pca %>% 
  merge(matrix_data_pca, 
        by.x = "Condition", 
        all.x = F, 
        all.y = F) %>% 
  select(Condition:Efficacy)

# Verifique quais colunas têm variância muito baixa
nearZeroVarCols <- nearZeroVar(matrix_data_pca_ready, saveMetrics = TRUE)
matrix_data_pca_ready <- matrix_data_pca_ready[, !nearZeroVarCols$nzv]
pca_res <- prcomp(matrix_data_pca_ready, scale. = TRUE)

# Crie o gráfico de PCA
pca_plot_ann = autoplot(pca_res, 
                    data = ann_vaccines_pca_matrix, 
                    colour = 'Vaccine', 
                    label = 1) + #1: display, 0: hide
  labs(title=filename) +
  theme_classic()
  # scale_color_manual(values = c(BBIBP = "#black", 
  #                               ZF2001 = "black",
  #                               BNT = "#56cfe1",
  #                               ChAd = "#80ffdb" ,
  #                               "ChAd-BNT" = "#72efdd")) 

pca_plot_not_ann = autoplot(pca_res, 
                    data = ann_vaccines_pca_matrix, 
                    colour = 'Vaccine', 
                    label = 0) + #1: display, 0: hide
  labs(title=filename) +
  theme_classic() +
  stat_ellipse(type = "t")

#Salvar
ggsave(pca_plot_not_ann, filename = paste0(filename, "_PCA_not-ann.png"), width = 10, height = 8)
ggsave(pca_plot_ann, filename = paste0(filename, "_PCA_ann.png"), width = 10, height = 8)

# Exiba o gráfico
print(pca_plot_ann)
print(pca_plot_not_ann)

############### KNN classification

#Determinar o número de clusters para KNN
pca_scores <- data.frame(pca_res$x[, 1:2])
ggp1 <- fviz_nbclust(pca_scores,  
                     FUNcluster = kmeans,
                     method = "wss")

ggp1 

set.seed(123)                             # Set seed for randomization
kmeans_clust <- kmeans(pca_scores,        # Perform k-means clustering
                        centers = 4) # Definir numero de clusters

#Visualizar clusters
ggp2 <- fviz_pca_ind(pca_res,
                   habillage = kmeans_clust$cluster,
                   repel = TRUE,
                   addEllipses = TRUE,
                   ellipse.type = "convex",
                   labelsize = 2) +
     guides(color = guide_legend(override.aes = list(label = ""))) +
  ggtitle(paste0(filename,  "KNN_Clustered.png"))

print(ggp2)
ggsave(ggp2, file = paste0(filename, "KNN_Clustered.png"), width = 5, height = 4)
########Correlation plot
#Matriz
corr_matrix = cor(matrix_data_pca_ready) 

#Plot
corrplot = ggcorrplot(corr_matrix, hc.order = TRUE) + 
  theme(axis.text.x = element_text(angle = 90, size = 5), 
        axis.text.y = element_text(size = 5))
#Salvar
ggsave(corrplot, file = paste0(filename, "_corrplot.png"), 
       width = 20, #Grande 20, pequeno 10
       height= 20) #Grande 20, pequeno 10
print(corrplot)

#########Scree plot
data.pca = princomp(corr_matrix) #PCA
summary(data.pca) #Retornar PCs

#########Scree plot
scree_plot = fviz_eig(data.pca, 
                      addlabels = TRUE,
                      ylim = c(0, 70)) +
  geom_col(color = "#00AFBB", fill = "#00AFBB") +
  theme_classic()

#Salvar
ggsave(scree_plot, file = paste0(filename, "_screeplot.png"), width = 10, height = 3) 
print(scree_plot)

#Comp1-Comp2
loadings = data.frame(data.pca$loadings[, 1:3])
loadings$Genes = rownames(loadings)
loadings_1 = arrange(loadings, desc(Comp.1))
loadings_2 = arrange(loadings, desc(Comp.2))
loadings_3 = arrange(loadings, desc(Comp.3))

#Plot
loadings_1_plot = ggplot(loadings_1, aes(x = reorder(Genes, -Comp.1), y=Comp.1, fill = Comp.1)) + 
  ggtitle(paste0("Comp1-Comp2 Genes", filename)) + 
  ylab("Comp1") +
  xlab("Genes") +
  geom_bar(stat = "identity") + 
  theme_light() +
  theme(axis.text.x = element_text(vjust = 0.1, hjust = 1, angle = 90, size = 3), 
        axis.text.y = element_text(size = 5),
        plot.title = element_text(size = 15L, hjust = 0.5)) + 
  scale_fill_continuous(type = "viridis") #cores
  
#Salvar
ggsave(loadings_1_plot, 
       file = paste0(filename, "_genescomp1-2.png"), 
       width = 10, height = 5)

print(loadings_1_plot)
# Graph of the variables
fviz_pca_var_genes = fviz_pca_var(data.pca, 
                                  col.ind = "cos2",
                                  gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"))

#Salvar
ggsave(fviz_pca_var_genes, file = paste0(filename, "_fviz_pca_var_genes.png"), width = 10)

######### COS2
cos2 = fviz_cos2(data.pca, 
                 choice = "var", 
                 axes = 1:2) + 
  theme(axis.text.x = element_text(angle=45, 
                                   size = 3)) +
  theme_light()

#Salvar
ggsave(cos2, file = paste0(filename, "_cos2.png"), width = 10, height = 5)

#Colorido
fviz_pca_var(data.pca, col.var = "cos2",
            gradient.cols = c("black", "orange", "green"),
            repel = TRUE)

#Print
print(fviz_pca_var_genes)
print(cos2)

CellMarker

#GSEA

Manual

######### INPUT AQUI ######### 
# all_degs_p_05_vac_infected = all_degs_p_05_vac_infected_27_11_23 %>%
#   mutate(condition = case_when(condition == "H-BNT-I (D1)" ~ "BNT-I (D1)",
#                                condition == "H-BNT-I (D3)" ~ "BNT-I (D3)",
#                                condition == "H-BNT-I (D4)" ~ "BNT-I (D4)",
#                                condition == "H-I-I (D2)" ~ "I-I (D2)",
#                                condition == "I-BNT-I (D2)" ~ "I-BNT-I (D2)",
#                                condition == "I-BNT-I (D5)" ~ "I-BNT-I (D5)",
#                                condition == "H-BNT-I (D10, mild)" ~ "BNT-I (D10, mild)",
#                                condition == "H-BNT-I (D10, severe)" ~ "BNT-I (D10, severe)",
#                                condition == "H-BNT-I (D26, mild)" ~ "BNT-I (D26, mild)",
#                                condition == "H-BNT-I (D26, severe)" ~ "BNT-I (D26, severe)",
#                                condition == "H-I (D10, moderate)" ~ "I (D10, moderate)",
#                                condition == "H-I (D10, severe)" ~ "I (D10, severe)",
#                                condition == "H-I (D26, moderate)" ~ "I (D26, moderate)",
#                                condition == "H-I (D26, severe)" ~ "I (D26, severe)",
#                                condition == "H-I (D51, moderate)" ~ "I (D51, moderate)",
#                                condition == "H-I (D51, severe)" ~ "I (D51, severe)",
#                                TRUE ~ condition))
# 
# write.csv(all_degs_p_05_vac_infected_27_11_23, file ="all_degs_p_05_vac_infected_29_11_23.csv")

all_degs_p_05_vac_infected

#GSE199750
# degs <- filter(all_degs_p_05_vac_infected, condition == "BNT (V1, D6)") #Não enriquecido
# degs <- filter(all_degs_p_05_vac_infected, condition == "BNT (V2, D1)") #Enriquecido
# degs <- filter(all_degs_p_05_vac_infected, condition == "BNT (V3, D1)") #Enriquecido
# degs <- filter(all_degs_p_05_vac_infected, condition == "BNT-MO (V3, D1)") #Enriquecido
# degs <- filter(all_degs_p_05_vac_infected, condition == "ChAd (V1, D6)") #Enriquecido
# degs <- filter(all_degs_p_05_vac_infected, condition == "ChAd (V2, D1)") #Enriquecido
# degs <- filter(all_degs_p_05_vac_infected, condition == "ChAd-BNT (V3, D1)") #Não enriquecido

#GSE201533
# degs = filter(all_degs_p_05_vac_infected, condition == "ChAd (V1, D3)") #Enriquecido
# degs = filter(all_degs_p_05_vac_infected, condition == "ChAd (V1, D7)") #Enriquecido
# degs = filter(all_degs_p_05_vac_infected, condition == "ChAd (V2, D3)") #Não enriquecido
# degs = filter(all_degs_p_05_vac_infected, condition == "ChAd (V2, D7)") #Enriquecido
# degs = filter(all_degs_p_05_vac_infected, condition == "ChAd-BNT (V2, D3)") #Enriquecido
# degs = filter(all_degs_p_05_vac_infected, condition == "ChAd-BNT (V2, D7)") #Enriquecido

#GSE206023
# degs = filter(all_degs_p_05_vac_infected, condition == "BBIBP (V3, D07)") #Enriquecido
# degs = filter(all_degs_p_05_vac_infected, condition == "BBIBP (V3, D14)") #Não enriquecido
# degs = filter(all_degs_p_05_vac_infected, condition == "BBIBP (V3, D28)") #Enriquecido
# degs = filter(all_degs_p_05_vac_infected, condition == "ZF2001 (V3, D07)") #Enriquecido
# degs = filter(all_degs_p_05_vac_infected, condition == "ZF2001 (V3, D14)") #Enriquecido
# degs = filter(all_degs_p_05_vac_infected, condition == "ZF2001 (V3, D28)") #Enriquecido

#GSE201530
# degs = filter(all_degs_p_05_vac_infected, condition == "BNT-I (D1)")
# degs = filter(all_degs_p_05_vac_infected, condition == "BNT-I (D3)")
# degs = filter(all_degs_p_05_vac_infected, condition == "BNT-I (D4)")
# degs = filter(all_degs_p_05_vac_infected, condition == "I-I (D2)")
# degs = filter(all_degs_p_05_vac_infected, condition == "I-BNT-I (D2)")
# degs = filter(all_degs_p_05_vac_infected, condition == "I-BNT-I (D5)")
# degs = filter(all_degs_p_05_vac_infected, condition == "I-I (D1)")
# degs = filter(all_degs_p_05_vac_infected, condition == "I-I (D3)")
# degs = filter(all_degs_p_05_vac_infected, condition == "I-I (D5)")


#GSE189039
# degs = filter(all_degs_p_05_vac_infected, condition == "BNT-I-BNT (D51, mild)")
# degs = filter(all_degs_p_05_vac_infected, condition == "BNT-I-BNT (D51, severe)")
# degs = filter(all_degs_p_05_vac_infected, condition == "BNT-I (D10, mild)")
# degs = filter(all_degs_p_05_vac_infected, condition == "BNT-I (D10, severe)")
# degs = filter(all_degs_p_05_vac_infected, condition == "BNT-I (D26, mild)")
# degs = filter(all_degs_p_05_vac_infected, condition == "BNT-I (D26, severe)")
# degs = filter(all_degs_p_05_vac_infected, condition == "I (D10, moderate)")
# degs = filter(all_degs_p_05_vac_infected, condition == "I (D10, severe)")
# degs = filter(all_degs_p_05_vac_infected, condition == "I (D26, moderate)")
# degs = filter(all_degs_p_05_vac_infected, condition == "I (D26, severe)")
# degs = filter(all_degs_p_05_vac_infected, condition == "I (D51, moderate)")
# degs = filter(all_degs_p_05_vac_infected, condition == "I (D51, severe)")
#Definir nome para arquivos gerados
file_name = degs %>% 
  select(condition) %>% 
  distinct() %>% 
  as.character()

######### DEGs para ORA ######### 
gene_list_ora <- degs$genes
######### DEGs para GSEA ######### 
degs_gene_list_lf2c <- degs$log2fold_change
names(degs_gene_list_lf2c) <- degs$genes
degs_gene_list_lf2c<-na.omit(original_gene_list)
degs_gene_list_lf2c = sort(degs_gene_list_lf2c, decreasing = TRUE)

############ IMMUNE GO
Immune_GO_T2G = ImmuneGO_Annotated_Genes_Nested_Interesting %>% 
  select(gene_set_short, genes)

immune_GO_gsea <- GSEA(degs_gene_list_lf2c, 
                       TERM2GENE = Immune_GO_T2G, 
                       minGSSize = 2,
                       maxGSSize = 1000,
                       pvalueCutoff = 0.25,
                       pAdjustMethod = "BH") %>% 
  as.data.frame() %>% 
  arrange(qvalue) %>% 
  mutate(condition = file_name,
         gsea_enrichment = "ImmuneGO")
preparing geneSet collections...
GSEA analysis...
leading edge analysis...
done...
#Salvar tabela
write.csv(immune_GO_gsea, file = paste(file_name, "ImmuneGO_GSEA.csv", sep = "_"))

########### CELL MARKER

CellMarker_genes = CellMarker_ImmuneCells %>% 
  select(cell_name, marker)

cell_types_gsea_immune <- GSEA(degs_gene_list_lf2c, 
                       TERM2GENE = CellMarker_genes, 
                       minGSSize = 1,
                       maxGSSize = 1000,
                       pvalueCutoff = 0.25, 
                       pAdjustMethod = "BH") %>% 
  as.data.frame() %>% 
  arrange(qvalue) %>% 
  mutate(condition = file_name,
         gsea_enrichment = "CellMarker")
preparing geneSet collections...
GSEA analysis...
leading edge analysis...
done...
#Salvar tabela
write.csv(cell_types_gsea_immune, file=paste(file_name, "CellMarker_GSEA.csv", sep = "_"))

########### VAX SIG DB

vax_sig_genes = VAX_Genes_Annotated_RAW %>% 
  select(STANDARD_NAME, GENE)

ora_degs_vax <- enricher(gene_list_ora, 
                       TERM2GENE = vax_sig_genes, 
                       minGSSize = 1,
                       maxGSSize = 1000,
                       pvalueCutoff = 0.25, 
                       pAdjustMethod = "BH")%>% 
  as.data.frame() %>% 
  arrange(qvalue) %>% 
  mutate(condition = file_name,
         gsea_enrichment = "VAXSig")

#Salvar 
write.csv(ora_degs_vax, file=paste(file_name, "VAXSig_ORA.csv", sep = "_"))

Automatizado

LS0tCnRpdGxlOiAiTmFpdmUgYW5kIGluZmVjdGVkIHBhdGllbnRzLCB2YWNjaW5hdGVkIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7cn0KbGlicmFyeShyZWFkcikKbGlicmFyeShxdmFsdWUpCmxpYnJhcnkoZXhwbG9yZSkKbGlicmFyeShtYWRpdHIpCmxpYnJhcnkoR0VPcXVlcnkpCmxpYnJhcnkoTWF0cml4KQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkocGhlYXRtYXApCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KGNlbGxkZXgpCmxpYnJhcnkoYmlvbWFSdCkKbGlicmFyeShvcmcuSHMuZWcuZGIpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KERFU2VxMikKbGlicmFyeShtc2lnZGJyKQpsaWJyYXJ5KGFwZSkKbGlicmFyeShHU1ZBKQpsaWJyYXJ5KHN2YSkKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkoY2x1c3RlclByb2ZpbGVyKQpsaWJyYXJ5KHBoZWF0bWFwKQpsaWJyYXJ5KGdwbG90cykKbGlicmFyeShFbmhhbmNlZFZvbGNhbm8pCmxpYnJhcnkobWV0YVJOQVNlcSkKbGlicmFyeShnZ2JlZXN3YXJtKQpsaWJyYXJ5KGVkaXREYXRhKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShjb3JycikKbGlicmFyeShnZ2NvcnJwbG90KQpsaWJyYXJ5KEZhY3RvTWluZVIpCmxpYnJhcnkoZmFjdG9leHRyYSkKbGlicmFyeShlc3F1aXNzZSkKbGlicmFyeShjb3J0bykKbGlicmFyeShjaXJjbGl6ZSkKbGlicmFyeShDb21wbGV4SGVhdG1hcCkKbGlicmFyeShqYW5pdG9yKQpgYGAKCgojIDEuIFByZXBhcmHDp8OjbyBkb3MgZGFkb3MKCiMjIDIuIERlZmluaXIgcGFkcsO1ZXMgZGUgZmlndXJhcwoKIyMjI0NvcmVzCmBgYHtyfQojIERlZmluaXIgdmFyacOhdmVpcyBkZSBjb3Jlcwp2YXhjb2xvcnMgPSBjKAogICJCQklCUCIgPSAiI2ZmZDAwMCIsCiAgIkJOVCIgPSAiIzU2Y2ZlMSIsCiAgIkNoQWQiID0gIiM4MGZmZGIiLAogICJDaEFkLUJOVCIgPSAiIzcyZWZkZCIsCiAgIlpGMjAwMSIgPSAiI2I1MTc5ZSIpCgpkb3NlX2NvbG9ycyA9IGMoCiAgICAiMSIgPSAiIzU2Y2ZlMSIsCiAgICAiMiIgPSAiIzU5NzhkNCIsCiAgICAiMyIgPSAiI2I1MTc5ZSIpCgpkYXlfY29sb3JzID0gYygKICAgICIxIiA9ICIjY2FmMGY4IiwKICAgICIzIiA9ICIjOTBlMGVmIiwKICAgICI2IiA9ICIjMDBiNGQ4IiwKICAgICI3IiA9ICIjMDA3N2I2IiwKICAgICIxNCIgPSAiIzAyM2U4YSIsCiAgICAiMjgiID0gIiMwMzA0NWUiKQoKdHlwZV9jb2xvcnMgPSBjKCdJTic9ICIjZmZkMDAwIiwgI0ZpcnN0IGdlbmVyYXRpb24gdmFjY2luZXMKICAgICAgICAgICAnTEEnID0gIiNmZmZmM2YiLAogICAgICAgICAgICdDT05KJyA9ICIjZjRhMjYxIiwKICAgICAgICAgICAnVkxQJyA9ICIjZGExZTM3IiwgI1NlY29uZCBnZW5lcmF0aW9uIHZhY2NpbmVzCiAgICAgICAgICAgJ1NVJyA9ICIjZmY0ZDZkIiwKICAgICAgICAgICAnUEVQJyA9ICIjZjQ4NDk4IiwKICAgICAgICAgICAnVlYnID0gIiM3MmVmZGQiLCAjVGhpcmQgZ2VuZXJhdGlvbiB2YWNjaW5lcwogICAgICAgICAgICdSTkEnID0gIiM1NmNmZTEiLAogICAgICAgICAgICdWVi1STkEnID0gIiM1ZTYwY2UiLAogICAgICAgICAgICdJTi1TVScgPSAiI2I1MTc5ZSIpCgpyZWdpbWVuX2NvbG9ycyA9IGMoJ0hPJyA9ICIjNTZjZmUxIiwKICAgICAgICAgICAgICAnSEUnID0gIiM1ZTYwY2UiKQoKaW1tdW5lX3N5c3RlbV9jb2xvcnMgPSBjKAogICAgIklubmF0ZSIgPSAiI2ZhZWRjZCIsCiAgICAiQWRhcHRpdmUiID0gIiNmZmI1YTciLAogICAgIkdlbmVyYWwiID0gIiM5OWQ5OGMiLAogICAgIk90aGVyIiA9ICIjZTVlNWU1IiwKICAgICJDb21wbGVtZW50IiA9ICIjNzQwMGI4IikKCmltbXVuZV9zdWJzeXN0ZW1fY29sb3JzID0gYygKICAgICJBZGFwdGl2ZSIgPSAiI2ZmYjVhNyIsCiAgICAiQ2VsbHVsYXIiID0gIiNmZjc1OGYiLAogICAgIkh1bW9yYWwiID0gIiNmZjc1OGYiLAogICAgIkFudGliYWN0ZXJpYWwiID0gIiM0ODk1ZWYiLAogICAgIkFudGlmdW5nYWwiID0gIiM0MzYxZWUiLAogICAgIkFudGltaWNyb2JpYWwiID0gIiM3NDAwYjgiLAogICAgIkdlbmVyYWwiID0gIiM5OWQ5OGMiLAogICAgIkFudGlnZW4gcHJlc2VudGF0aW9uIiA9ICIjZTRjNGE1IiwKICAgICJBUEMiID0gIiNjY2Q1YWUiLAogICAgIkVvc2lub3BoaWwiID0gIiNmYWVkY2QiLAogICAgIkdyYW51bG9jeXRlIiA9ICIjZmFlZGNkIiwKICAgICJMZXVrb2N5dGUiID0gIiNmZmI1YTciLAogICAgIk5ldXRyb3BoaWwiID0gIiNjY2Q1YWUiLAogICAgIklubmF0ZSBpbW11bmUgcmVzcG9uc2UiID0gIiNmYWVkY2QiLAogICAgIkludGVyZmVyb24iID0gIiNhNGMzYjIiLAogICAgIkFudGl2aXJhbCIgPSAiIzYwNDk1YSIsCiAgICAiUGF0dGVybiByZWNvZ25pdGlvbiByZWNlcHRvciIgPSAiI2Y0ZjRkNSIsCiAgICAiTmF0dXJhbCBraWxsZXIiID0gIiNmZWRkOTYiLAogICAgIk11Y29zYSIgPSAiI2MzZGZlMCIsCiAgICAiRXJ5dGhyb2N5dGUiID0gIiM0ODk1ZWYiKQoKCgojIyMjIyMjIyMjIENvbG9ycyBkaWN0aW9uYXJ5CgojVmFjY2luZXMKYW5uX2NvbG9ycyA9IGxpc3QoCiAgdmFjY2luZSA9IGMoCiAgIkJCSUJQIiA9ICIjZGVlMmU2IiwKICAiQk5UIiA9ICIjNTZjZmUxIiwKICAiQ2hBZCIgPSAiIzgwZmZkYiIsCiAgIkNoQWQtQk5UIiA9ICIjNWU2MGNlIiwKICAiWkYyMDAxIiA9ICIjYjUxNzllIiwKICAiSU5GRUNUSU9OIiA9ICIjZmY0ZDZkIiwKICAiSU5GRUNUSU9OLVZBQ0NJTkUiPSAiI2ZmY2NkNSIpLAogIGRvc2UgPSBjKAogICAgIk5BIiA9ICJ3aGl0ZSIsCiAgICAiMCIgPSAid2hpdGUiLAogICAgIjEiID0gIiM1NmNmZTEiLAogICAgIjIiID0gIiM1OTc4ZDQiLAogICAgIjMiID0gIiNiNTE3OWUiKSwKICBkYXkgPSBjKAogICAgIjAiID0gIndoaXRlIiwKICAgICIxIiA9ICIjY2FmMGY4IiwKICAgICIyIiA9ICIjYWRlOGY0IiwKICAgICIzIiA9ICIjOTBlMGVmIiwKICAgICI0IiA9ICIjNkNENUVBIiwKICAgICI1IiA9ICIjNDhjYWU0IiwKICAgICI2IiA9ICIjMDBiNGQ4IiwKICAgICI3IiA9ICIjMDA5NmM3IiwKICAgICIxMCIgPSAiIzAwODdCRiIsCiAgICAiMTQiID0gIiMwMDc3YjYiLAogICAgIjI2IiA9ICIjMDE1QkEwIiwKICAgICIyOCIgPSAiIzAyM2U4YSIsCiAgICAiNTEiID0gIiMwMzA0NWUiKSwKICB0eXBlID0gYygnSU4nPSAiI2U1ZTVlNSIsICMxc3QgR2VuICB2YWNjaW5lcwogICAgICAgICAgICdTVScgPSAiIzAwYTg5NiIsCiAgICAgICAgICAgJ1ZWJyA9ICIjNzJlZmRkIiwgIzNyZCBHZW4gdmFjY2luZXMKICAgICAgICAgICAnUk5BJyA9ICIjNTZjZmUxIiwKICAgICAgICAgICAnVlYtUk5BJyA9ICIjNWU2MGNlIiwgI0hldGVyb2xvZ291cwogICAgICAgICAgICdJTi1TVScgPSAiI2I1MTc5ZSIsCiAgICAgICAgICAgJ0lORkVDVElPTic9ICIjZGExZTM3IiksICNJbmZlY3Rpb24KICByZWdpbWVuID0gYygnSE8nID0gImdyZXk5MCIsCiAgICAgICAgICAgICAgJ0hFJyA9ICIjOGQ5OWFlIiwKICAgICAgICAgICAgICAiVi1JLVYiID0gIiMzNjI0OGYiLAogICAgICAgICAgICAgICJWLUkiID0gIiNEN0IwRUUiLAogICAgICAgICAgICAgICJJLVYtSSIgPSAiIzc0MDBiOCIsCiAgICAgICAgICAgICAgIkktSSIgPSAiIzUzOTBkOSIsCiAgICAgICAgICAgICAgIkkiID0gIiM2NGRmZGYiKSwKICBpbmZlY3Rpb24gPSBjKCJub25lIiA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgICAiMSIgPSAiIzU2Y2ZlMSIsCiAgICAgICAgICAgICAgICAiMiIgPSAiIzVlNjBjZSIpLAogIHZhcmlhbnQgPSBjKCJOQSIgPSAid2hpdGUiLAogICAgICAgICAgICAgICJCZXRhIiA9ICIjNzJlZmRkIiwKICAgICAgICAgICAgICAiT21pY3JvbiIgPSAiIzVlNjBjZSIpLAogIHNldmVyaXR5ID0gYygiQSAoOSUpIE1JICg4MSUpIE1PICgwKSBTICg0JSkiID0gIiNjYWYwZjgiLAogICAgICAgICAgICAgICAiQSAoMjklKSBNSSAoNTclKSBNTyAoMTQpIFMgKDAlKSIgPSAiIzU2Y2ZlMSIsCiAgICAgICAgICAgICAgICJBICgwJSkgTUkgKDg5JSkgTU8gKDExJSkgUyAoMCUpIiA9ICIjNzJlZmRkIiwKICAgICAgICAgICAgICAgIkEgKDklKSBNSSAoNDclKSBNTyAoMjElKSBTICgzJSkiID0gIiM2NGRmZGYiLAogICAgICAgICAgICAgICAiUyIgPSAiIzVlNjBjZSIsCiAgICAgICAgICAgICAgICJNTyIgPSAiIzY0ZGZkZiIsCiAgICAgICAgICAgICAgICJNSSIgPSAiIzcyZWZkZCIsCiAgICAgICAgICAgICAgICJOQSIgPSAid2hpdGUiKSkKCiNSb3dzCiMgYW5uX2dlbmVzZXRzX2hlYXRtYXAKYW5uX2NvbG9yc19yb3dzID0gbGlzdCgKICBgaW1tdW5lX3N5c3RlbWAgPSBjKAogICAgIklubmF0ZSIgPSAiI2ZhZWRjZCIsCiAgICAiQWRhcHRpdmUiID0gIiNmZmI1YTciLAogICAgIkdlbmVyYWwiID0gIiM5OWQ5OGMiLAogICAgIk90aGVyIiA9ICIjZTVlNWU1IiwKICAgICJDb21wbGVtZW50IiA9ICIjNzQwMGI4IiwKICAgICJObyBlbnJpY2htZW50IiA9ICJncmF5OTAiCiAgKSwKICBgaW1tdW5lX3N1Yl9zeXN0ZW1gID0gYygKICAgICJBZGFwdGl2ZSIgPSAiI2ZmYjVhNyIsCiAgICAiQ2VsbHVsYXIiID0gIiNmZjc1OGYiLAogICAgIkh1bW9yYWwiID0gIiNmZjc1OGYiLAogICAgIkFudGliYWN0ZXJpYWwiID0gIiM0ODk1ZWYiLAogICAgIkFudGlmdW5nYWwiID0gIiM0MzYxZWUiLAogICAgIkFudGltaWNyb2JpYWwiID0gIiM3NDAwYjgiLAogICAgIkdlbmVyYWwiID0gIiM5OWQ5OGMiLAogICAgIkFudGlnZW4gcHJlc2VudGF0aW9uIiA9ICIjZTRjNGE1IiwKICAgICJBUEMiID0gIiNjY2Q1YWUiLAogICAgIkVvc2lub3BoaWwiID0gIiNmYWVkY2QiLAogICAgIkdyYW51bG9jeXRlIiA9ICIjZmFlZGNkIiwKICAgICJMZXVrb2N5dGUiID0gIiNmZmI1YTciLAogICAgIk5ldXRyb3BoaWwiID0gIiNjY2Q1YWUiLAogICAgIklubmF0ZSBpbW11bmUgcmVzcG9uc2UiID0gIiNmYWVkY2QiLAogICAgIkludGVyZmVyb24iID0gIiNhNGMzYjIiLAogICAgIkFudGl2aXJhbCIgPSAiIzYwNDk1YSIsCiAgICAiUGF0dGVybiByZWNvZ25pdGlvbiByZWNlcHRvciIgPSAiI2Y0ZjRkNSIsCiAgICAiTmF0dXJhbCBraWxsZXIiID0gIiNmZWRkOTYiLAogICAgIk11Y29zYSIgPSAiI2MzZGZlMCIsCiAgICAiRXJ5dGhyb2N5dGUiID0gIiM0ODk1ZWYiLAogICAgIk5vIGVucmljaG1lbnQiID0gImdyYXk5MCIKICApCikKICAKCmBgYAoKCgojIDMuIFNlbGXDp8OjbyBkZSBlc3R1ZG9zCgoKYGBge3J9CiMgR1NFMTg5MDM5CiMgR1NFMjAxNTMwCmBgYAoKIyMgMy4xIEJhaXhhciBkYWRvcwoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KI0JhaXhhciBkYWRvcyBkZSB1bWEgbGlzdGEgZGUgZXN0dWRvcwoKIyMjIyMjIyMjIyMjIE9idGVyIFRhYmVsYSBkZSBjb3VudHMKI0dFTyBzdXBwbGVtZW50YXJ5IGZpbGVzLiBCYWl4YXIgaW5kaXZpZHVhbG1lbnRlLiBBcnF1aXZvcyBncmFuZGVzIGRldmVtIHNlciBiYWl4YWRvcyBkaXJldG8gZG8gbmF2ZWdhZG9yLgpnZXRHRU9TdXBwRmlsZXMoJ0dTRTE4OTAzOScpICMgQmFpeGFyIHRhYmVsYSBkZSBjb3VudHMKdW50YXIoJ0dTRTE4OTAzOV9SQVcudGFyJykgIyBEZXNjb21wYWN0YXIgdGFyIHppcHBlZAojZ3VuemlwKCJHU0UxNzQ2MjFfUkFXLnRhciIpICMgRGVzY29tcGFjdGFyIGd1bnppcCAoLmd6KQoKCiMjIyMjIyMjIyMjIyBNZXRhZGFkb3MKCmZpbGVuYW1lID0gIkdTRTE4OTAzOSIKR1NFMTg5MDM5IDwtIGdldEdFTygiR1NFMTg5MDM5IiwgR1NFTWF0cml4ID0gVFJVRSkgI1VzZSBHU0VNYXRyaXggPSBUUlVFIHBhcmEgb2J0ZXIgbWV0YWRhZG9zIGRlIGNhZGEgYW1vc3RyYQpHU0UxODkwMzkgPC0gR1NFMTg5MDM5W1sxXV0gI0FuYWxpc2FyIG8gcHJpbWVpcm8gb2JqZXRvIGRhIGxpc3RhLiAKCiMjIyMjIyMjIyMjIyNBbmFsaXNhciBpbmZvcm1hw6fDtWVzIHNvYnJlIGFtb3N0cmFzLiAKCkdTRTE4OTAzOV9tZXRhZGF0YSA9IEdTRTE4OTAzOSAlPiUgCiAgcERhdGEoKSAlPiUgI0luZm9ybWHDp8O1ZXMgc29icmUgYW1vc3RyYXMgCiAgc2VsZWN0KCAjU2VsZWNpb25hciBlIHJlbm9tZWFyIGNvbHVuYXMgZGUgaW50ZXJlc3NlCiAgICBnZW9fc2FtcGxlID0gImdlb19hY2Nlc3Npb24iLCAKICAgIHN1YmplY3RfaWQgPSAidGl0bGUiLCBhZ2UgPSAiYWdlOmNoMSIsIAogICAgc2V4ID0gImdlbmRlcjpjaDEiLCBkaXNlYXNlX3N0YXRlID0gImRpc2VhcyBzdGF0ZTpjaDEiLCAKICAgIHNldmVyaXR5ID0gInNldmVyaXR5OmNoMSIpIAoKd3JpdGUuY3N2KEdTRTE4OTAzOV9tZXRhZGF0YSwgZmlsZSA9ICJHU0UxODkwMzlfbWV0YWRhdGEuY3N2IikgI1Rlcm1pbmFyIGRlIGFub3RhciBubyBleGNlbAoKYGBgCgoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KIyMjIyMjIyMjIyMjIE9idGVyIFRhYmVsYSBkZSBjb3VudHMKI0dFTyBzdXBwbGVtZW50YXJ5IGZpbGVzLiBCYWl4YXIgaW5kaXZpZHVhbG1lbnRlLiBBcnF1aXZvcyBncmFuZGVzIGRldmVtIHNlciBiYWl4YWRvcyBkaXJldG8gZG8gbmF2ZWdhZG9yLgpnZXRHRU9TdXBwRmlsZXMoJ0dTRTIwMTUzMCcpICMgQmFpeGFyIHRhYmVsYSBkZSBjb3VudHMKdW50YXIoJ0dTRTIwMTUzMF9SQVcudGFyJykgIyBEZXNjb21wYWN0YXIgdGFyIHppcHBlZAoKIyMjIyMjIyMjIyMjIE1ldGFkYWRvcwoKZmlsZW5hbWUgPSAiR1NFMjAxNTMwIgpHU0UyMDE1MzAgPC0gZ2V0R0VPKCJHU0UyMDE1MzAiLCBHU0VNYXRyaXggPSBUUlVFKSAjVXNlIEdTRU1hdHJpeCA9IFRSVUUgcGFyYSBvYnRlciBtZXRhZGFkb3MgZGUgY2FkYSBhbW9zdHJhCkdTRTIwMTUzMCA8LSBHU0UyMDE1MzBbWzFdXSAjQW5hbGlzYXIgbyBwcmltZWlybyBvYmpldG8gZGEgbGlzdGEuIAoKIyMjIyMjIyMjIyMjI0FuYWxpc2FyIGluZm9ybWHDp8O1ZXMgc29icmUgYW1vc3RyYXMuIAoKR1NFMjAxNTMwX21ldGFkYXRhID0gR1NFMjAxNTMwICU+JSAKICBwRGF0YSgpICU+JSAjSW5mb3JtYcOnw7VlcyBzb2JyZSBhbW9zdHJhcyAKICBzZWxlY3QoCiAgICBnZW9fc2FtcGxlID0gImdlb19hY2Nlc3Npb24iLCAKICAgIHN1YmplY3RfaWQgPSAidGl0bGUiLCAKICAgIGFnZSA9ICJhZ2U6Y2gxIiwgCiAgICBzZXggPSAiZ2VuZGVyOmNoMSIsIAogICAgZGlzZWFzZV9zdGF0ZSA9ICJkaXNlYXNlIHN0YXRlOmNoMSIsIAogICAgdGltZXBvaW50ID0gImRheXMgYWZ0ZXIgcG9zaXRpdmUgcGNyIHJlc3VsdHM6Y2gxIiwKICAgIGdyb3VwID0gImdyb3VwIChieSBjb3ZpZC0xOSB2YWNjaW5hdGlvbiwgcHJpb3IgaW5mZWN0aW9uKTpjaDEiLAogICAgdmFyaWFudCA9ICJvbWljcm9uIHN1YmxpbmVhZ2U6Y2gxIikgCgp3cml0ZS5jc3YoR1NFMjAxNTMwX21ldGFkYXRhLCBmaWxlID0gIkdTRTIwMTUzMF9tZXRhZGF0YS5jc3YiKQoKI0Fub3RhciBubyBleGNlbCBjb20gZGFkb3MgZG8gYXJ0aWdvCmBgYAoKKkxlciBhcnF1aXZvcyBlIHRyYW5zZm9ybWFyIGVtIHRhYmVsYSoKCkFicmEgYSBsaXN0YSBkbyBlc3R1ZG8gZSBhbmFsaXNlIHN1YXMgaW5mb3JtYcOnw7Vlcy4gQW8gZGVzY29tcGFjdGFyLCBzdXJnZW0gZGl2ZXJzb3MgYXJxdWl2b3MgIi5mZWF0dXJlQ291bnRzLnR4dC5neiIsIHF1ZSBkZXZlbSBzZXIgZGVzY29tcGFjdGFkb3MuIFBhcmEgZGVzY29tcGFjdGFyIGEgbGlzdGEgZGUgYXJxdWl2b3MsIHVzZSB1bSBsb29wLgoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KI0Rlc2NvbXBhY3RhciB0b2RvcyBvcyBhcnF1aXZvcwpkaXJldG9yaW8gPC0gIn4vRGVza3RvcC9STkEgc2VxIC0gV2FzaW0vR1NFMTg5MDM5IgphcnF1aXZvcyA8LSBsaXN0LmZpbGVzKHBhdGggPSBkaXJldG9yaW8sIHBhdHRlcm4gPSAiKi5neiQiLCBmdWxsLm5hbWVzID0gVFJVRSkKZm9yKGFycXVpdm9fZ3ogaW4gYXJxdWl2b3MpIHtndW56aXAoYXJxdWl2b19neil9CgojTGVyIGFycXVpdm9zIGRvIGVzdHVkbyBlc3BlY8OtZmljbwpkaXJldG9yaW9fR1NFMjAxNTMwIDwtICJ+L0Rlc2t0b3AvUk5BIHNlcSAtIFdhc2ltL0dTRTIwMTUzMCIKZGlyZXRvcmlvX0dTRTE4OTAzOSA8LSAifi9EZXNrdG9wL1JOQSBzZXEgLSBXYXNpbS9HU0UxODkwMzkiCgphcnF1aXZvc190eHRfR1NFMjAxNTMwIDwtIGxpc3QuZmlsZXMocGF0aCA9IGRpcmV0b3Jpb19HU0UyMDE1MzAsIHBhdHRlcm4gPSAiKi50eHQkIiwgZnVsbC5uYW1lcyA9IFRSVUUpCmFycXVpdm9zX3R4dF9HU0UxODkwMzkgPC0gbGlzdC5maWxlcyhwYXRoID0gZGlyZXRvcmlvX0dTRTE4OTAzOSwgcGF0dGVybiA9ICIqLnR4dCQiLCBmdWxsLm5hbWVzID0gVFJVRSkKCiMgRnVuw6fDo28gcGFyYSBsZXIgZSBhanVzdGFyIG9zIGFycXVpdm9zCmxlcl9lX2FqdXN0YXIgPC0gZnVuY3Rpb24oYXJxdWl2bykgewogIGRhZG9zIDwtIHJlYWQudGFibGUoYXJxdWl2bywgaGVhZGVyID0gRkFMU0UsIHNlcCA9ICJcdCIpCiAgaWYgKG5jb2woZGFkb3MpID49IDIpIHsKICAgIGNvbG5hbWVzKGRhZG9zKVsxOjJdIDwtIGMoImdlbmVzIiwgdG9vbHM6OmZpbGVfcGF0aF9zYW5zX2V4dChiYXNlbmFtZShhcnF1aXZvKSkpCiAgICByZXR1cm4oZGFkb3MpCiAgfSBlbHNlIHsKICAgIHJldHVybihOVUxMKQogIH0KfQoKIyBMZXIgZSBhanVzdGFyIHRvZG9zIG9zIGFycXVpdm9zIG5hIGxpc3RhCmxpc3RhX2RhZG9zX0dTRTIwMTUzMCA8LSBsYXBwbHkoYXJxdWl2b3NfdHh0X0dTRTIwMTUzMCwgbGVyX2VfYWp1c3RhcikKbGlzdGFfZGFkb3NfR1NFMTg5MDM5IDwtIGxhcHBseShhcnF1aXZvc190eHRfR1NFMTg5MDM5LCBsZXJfZV9hanVzdGFyKQoKIyBGaWx0cmFyIGVsZW1lbnRvcyBOVUxMIGRhIGxpc3RhIGUgdW5pciBvcyBkYXRhZnJhbWVzCmNvdW50c19nc2UyMDE1MzAgPC0gbGlzdGFfZGFkb3NfR1NFMjAxNTMwICU+JQogIHB1cnJyOjpkaXNjYXJkKGlzLm51bGwpICU+JQogIHJlZHVjZShmdWxsX2pvaW4sIGJ5ID0gImdlbmVzIikKCmNvdW50c19HU0UxODkwMzkgPC0gbGlzdGFfZGFkb3NfR1NFMTg5MDM5ICU+JQogIHB1cnJyOjpkaXNjYXJkKGlzLm51bGwpICU+JQogIHJlZHVjZShmdWxsX2pvaW4sIGJ5ID0gImdlbmVzIikKCiMgUmVub21lYXIgYXMgY29sdW5hcyBleGNldG8gYSBwcmltZWlyYSAoImdlbmVzIikKY29sbmFtZXMoY291bnRzX2dzZTIwMTUzMClbLTFdIDwtIGdzdWIoIl5bXl9dK18oLiopIiwgIlxcMSIsIGNvbG5hbWVzKGNvdW50c19nc2UyMDE1MzApWy0xXSkKY29sbmFtZXMoY291bnRzX0dTRTE4OTAzOSlbLTFdIDwtIGdzdWIoIl5bXl9dK18oLiopIiwgIlxcMSIsIGNvbG5hbWVzKGNvdW50c19HU0UxODkwMzkpWy0xXSkKCgojIExlciBlIGFqdXN0YXIgdG9kb3Mgb3MgYXJxdWl2b3MgbmEgbGlzdGEKbGlzdGFfZGFkb3NfR1NFMjAxNTMwIDwtIGxhcHBseShhcnF1aXZvc190eHRfR1NFMjAxNTMwLCBsZXJfZV9hanVzdGFyKQpsaXN0YV9kYWRvc19HU0UxODkwMzkgPC0gbGFwcGx5KGFycXVpdm9zX3R4dF9HU0UxODkwMzksIGxlcl9lX2FqdXN0YXIpCgojIEZpbHRyYXIgZWxlbWVudG9zIE5VTEwgZGEgbGlzdGEgZSB1bmlyIG9zIGRhdGFmcmFtZXMKY291bnRzX2dzZTIwMTUzMCA8LSBsaXN0YV9kYWRvc19HU0UyMDE1MzAgJT4lCiAgcHVycnI6OmRpc2NhcmQoaXMubnVsbCkgJT4lCiAgcmVkdWNlKGZ1bGxfam9pbiwgYnkgPSAiZ2VuZXMiKQoKY291bnRzX0dTRTE4OTAzOSA8LSBsaXN0YV9kYWRvc19HU0UxODkwMzkgJT4lCiAgcHVycnI6OmRpc2NhcmQoaXMubnVsbCkgJT4lCiAgcmVkdWNlKGZ1bGxfam9pbiwgYnkgPSAiZ2VuZXMiKQoKIyBSZW5vbWVhciBhcyBjb2x1bmFzIGV4Y2V0byBhIHByaW1laXJhICgiZ2VuZXMiKQpjb2xuYW1lcyhjb3VudHNfZ3NlMjAxNTMwKVstMV0gPC0gZ3N1YigiXlteX10rXyguKikiLCAiXFwxIiwgY29sbmFtZXMoY291bnRzX2dzZTIwMTUzMClbLTFdKQpjb2xuYW1lcyhjb3VudHNfR1NFMTg5MDM5KVstMV0gPC0gZ3N1YigiXlteX10rXyguKikiLCAiXFwxIiwgY29sbmFtZXMoY291bnRzX0dTRTE4OTAzOSlbLTFdKQoKI1NhbHZhcgp3cml0ZS5jc3YoY291bnRzX2dzZTIwMTUzMCwgZmlsZSA9ICJnc2UyMDE1MzBfY291bnRzLmNzdiIpCndyaXRlLmNzdihjb3VudHNfR1NFMTg5MDM5LCBmaWxlID0gImdzZTE4OTAzOV9jb3VudHMuY3N2IikKCmBgYAoKCgojIDQuIEFuw6FsaXNlIGRlIGRhZG9zCgojIyA0LjEuIEFuw6FsaXNlIGRlIGV4cHJlc3PDo28gZ2VuaWNhIGRpZmVyZW5jaWFsCgoqUGFkcm9uaXphbmRvIHRhYmVsYSBkZSBjb3VudHMqCgpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQoKIyMjIyMjIyMjIyMjIyMjIEdTRTIwMTUzMAojIE9yZGVuYXIgdGFiZWxhCmdzZTIwMTUzMF9jb3VudHNfcmVhZHkgPC0gY291bnRzX2dzZTIwMTUzMCAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoImdlbmVzIikgJT4lIAogIHQoKSAlPiUKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigic2FtcGxlIikgJT4lIAogIGFycmFuZ2Uoc2FtcGxlKSAlPiUgCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJzYW1wbGUiKSAlPiUgCiAgdCgpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCJnZW5lcyIpICU+JSAKICBmaWx0ZXIoIWdyZXBsKCJfIiwgZ2VuZXMpKSAlPiUgCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJnZW5lcyIpCgojIFNhbHZhciBhcnF1aXZvIGNvbSByb3duYW1lcwpzYXZlUkRTKGdzZTIwMTUzMF9jb3VudHNfcmVhZHksIGZpbGUgPSAiZ3NlMjAxNTMwX2NvdW50c19yZWFkeS5yZHMiKQoKCiMjIyMjIyMjIyMjIyMjIyBHU0UxODkwMzkKIyBPcmRlbmFyIHRhYmVsYQpnc2UxODkwMzlfY291bnRzX3JlYWR5IDwtIGNvdW50c19HU0UxODkwMzkgJT4lCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJnZW5lcyIpICU+JSAKICB0KCkgJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByb3duYW1lc190b19jb2x1bW4oInNhbXBsZSIpICU+JSAKICBhcnJhbmdlKHNhbXBsZSkgJT4lIAogIGNvbHVtbl90b19yb3duYW1lcygic2FtcGxlIikgJT4lIAogIHQoKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigiZ2VuZXMiKSAlPiUgCiAgZmlsdGVyKCFncmVwbCgiXyIsIGdlbmVzKSkgJT4lIAogIGNvbHVtbl90b19yb3duYW1lcygiZ2VuZXMiKQoKIyBTYWx2YXIgYXJxdWl2byBjb20gcm93bmFtZXMKc2F2ZVJEUyhnc2UxODkwMzlfY291bnRzX3JlYWR5LCBmaWxlID0gImdzZTE4OTAzOV9jb3VudHNfcmVhZHkucmRzIikKCkdTRTE4OTAzOV9tZXRhZGF0YQoKYGBgCgoqTWV0YWRhdGEqCgpBIHRhYmVsYSBkZSBjb3VudHMgZm9ybmVjaWRhIHBlbG8gZXN0dWRvIMOpIG5vbWVhZGEgY29tIG8gU3ViamVjdCBJRCArIFRpbWVwb2ludCBlIG7Do28gY29tIG8gY29kaWdvIEdTTS4gUG9yIGlzc28sIHRlcmVtb3MgZGUgdHJhdGFyIGEgdGFiZWxhIGRlIG1ldGFkYWRvcy4gQWzDqW0gZGlzc28sIGVsYSBuw6NvIHBvc3N1aSBhIGNvbHVuYSBkZSBpZGFkZS4gw4kgcG9zc8OtdmVsIG1hbmlwdWxhciBlc3RlcyBkYWRvcyBubyBleGNlbC4KCgoqREVTRVEyKgoKKlByZXBhcmFuZG8gZGFkb3MqCgoKIyMgR1NFMjAxNTMwCgpgYGB7cn0KIyMjREVTRVEyIC0gUEYgdmVyc3VzIEFaLCBQRiBlbSBkaWZlcmVudGVzIHRlbXBvcywgQVogZW0gZGlmZXJlbnRlcyB0ZW1wb3MKCiMjIyNEZWZpbmluZG8gZGVzaWduCgojIyMjIyMgUGFkcm9uaXplIGFzIHZhcmnDoXZlaXMgCmNvdW50RGF0YSA8LSBnc2UyMDE1MzBfY291bnRzX3JlYWR5CmNvbERhdGEgPC0gR1NFMjAxNTMwX21ldGFkYXRhICU+JQogIG11dGF0ZSgKICAgIHRpbWVwb2ludF9kYXkgPSBmYWN0b3IodGltZXBvaW50X2RheSksCiAgICBhZ2UgPSBmYWN0b3IoYWdlKSwKICAgIHNleCA9IGZhY3RvcihzZXgpLAogICAgZGlzZWFzZV92YWMgPSBmYWN0b3IoZGlzZWFzZV92YWMpLAogICAgZG9zZSA9IGZhY3Rvcihkb3NlKSwKICAgIGRpc2Vhc2VfdGltZSA9IHBhc3RlMChkaXNlYXNlX3ZhYywgIl9EIiwgdGltZXBvaW50X2RheSkpICU+JSAKICBzZWxlY3Qoc3ViamVjdF9pZCwgZXZlcnl0aGluZygpKQoKCiMjIyMjIyBDcmllIG8gb2JqZXRvIERFU2VxRGF0YVNldCAjIyMjIyMKIyBPIGRlc2lnbiBkZXZlIGluY2x1aXIgdG9kb3Mgb3MgZmF0b3JlcyBxdWUgcG9kZW0gaW5mbHVlbmNpYXIgc2lnbmlmaWNhdGl2YW1lbnRlIG9zIGRhZG9zLiBDb2xvcXVlIHBvciDDumx0aW1vIG8gZmF0b3IgZGUgaW50ZXJlc3NlIHByaW5jaXBhbCAtIG5vIGNhc28sIG8gZmF0b3IgZGUgcHJpbWVpcmEgb3Ugc2VndW5kYSBkb3NlcywgcG9pcyBuZXN0YSBwcmltZWlyYSBldGFwYSBuw6NvIHNlcsOjbyBhbmFsaXNhZG9zIG9zIGVmZWl0b3MgZGUgdW1hIHRlcmNlaXJhIGRvc2UgZGUgdmFjaW5hIGhldGVyw7Nsb2dhLgoKZGRzIDwtIERFU2VxRGF0YVNldEZyb21NYXRyaXgoY291bnREYXRhID0gY291bnREYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sRGF0YSA9IGNvbERhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSB+IGRpc2Vhc2VfdGltZSkKCiMjIyMjIyBQcsOpLWZpbHRyYWdlbSAjIyMjIyMKI01hbnRlbmhhIG9zIGdlbmVzIGNvbSBwZWxvIG1lbm9zIDEwIGxlaXR1cmFzIG5vIHRvdGFsLgoKa2VlcCA8LSByb3dTdW1zKGNvdW50cyhkZHMpKSA+PSAxMApkZHMgPC0gZGRzW2tlZXAsXQoKYGBgCgoqRXhlY3V0YW5kbyBERVNFUTIqCgpgYGB7cn0KIyMjIyMjIEV4ZWN1dGFyIERFU2VxICMjIyMjIwoKI0V4ZWN1dGFyIERFU2VxIGNvbSBtw6l0b2RvIFdhbGQKZGRzIDwtIERFU2VxKGRkcykKCiNTYWx2YXIKd3JpdGVfcmRzKGRkcyxmaWxlPSJnc2UyMDE1MzBfZGRzX0RFU2VxMl9XYWxkX2Rpc2Vhc2VfdmFjX3RpbWUucmRzIikKCiMjIyMjIyBPYnRlciBjb21wYXJhw6fDtWVzIHJlYWxpemFkYXMgIyMjIyMjCnJlc3VsdHNOYW1lcyhkZHMpCgpkZHMgPSBnc2UyMDE1MzBfZGRzX0RFU2VxMl9XYWxkX2Rpc2Vhc2VfdmFjX3RpbWVwb2ludF9kYXkKCiMjIyMjIyBPYnRlbmRvIG9zIERFR3MgdG90YWlzICMjIyMjIwpyZXMgPC0gcmVzdWx0cyhkZHMpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIGZpbHRlcihwdmFsdWUgPCAwLjA1KQoKI1NhbHZhciB0YWJlbGEKd3JpdGUuY3N2KHJlcywgZmlsZSA9ICJnc2UyMDE1MzBfZGRzX0RFU2VxMl9XYWxkX2Rpc2Vhc2VfdmFjX0FORF90aW1lcG9pbnRfZGF5X0FMTERFR1MucmRzIiwgcm93Lm5hbWVzID0gVFJVRSkKCmBgYAoKKkNvbXBhcmFuZG8gdGVtcG9zIGUgY29uZGnDp8O1ZXMqCgpOZXN0YSBjb21wYXJhw6fDo28sIHPDo28gZW5jb250cmFkYXMgREVHcyBkZSBjYWRhIHZhY2luYSBpbmRpdmlkdWFsIG5vcyBkaWZlcmVudGVzIHRlbXBvcy4gUGFyYSBjb21wYXJhciB1bWEgdmFjaW5hIGNvbSBhIG91dHJhIGVtIGRpZmVyZW50ZXMgdGVtcG9zLCDDqSBuZWNlc3PDoXJpbyB1c2FyIG9zIGFyZ3VtZW50b3MgImNvbnRyYXN0IiBvdSAibmFtZSIuCgpgYGB7cn0KI0gtQk5ULUkKIyBjb250cmFzdCA9IGMoImRpc2Vhc2VfdGltZSIsICJILkJOVC5JX0QxIiwgIkhfRDAiKQojIGNvbnRyYXN0ID0gYygiZGlzZWFzZV90aW1lIiwgIkguQk5ULklfRDIiLCAiSF9EMCIpIChOQU8gREVVKQojIGNvbnRyYXN0ID0gYygiZGlzZWFzZV90aW1lIiwgIkguQk5ULklfRDMiLCAiSF9EMCIpCiMgY29udHJhc3QgPSBjKCJkaXNlYXNlX3RpbWUiLCAiSC5CTlQuSV9ENCIsICJIX0QwIikKCiNJLUJOVC1JCiMgY29udHJhc3QgPSBjKCJkaXNlYXNlX3RpbWUiLCAiSS5CTlQuSV9EMiIsICJIX0QwIikKIyBjb250cmFzdCA9IGMoImRpc2Vhc2VfdGltZSIsICJJLkJOVC5JX0Q1IiwgIkhfRDAiKQoKI0gtSQojIGNvbnRyYXN0ID0gYygiZGlzZWFzZV90aW1lIiwgIkguSV9EMSIsICJIX0QwIikKCiNILUktSQojIGNvbnRyYXN0ID0gYygiZGlzZWFzZV90aW1lIiwgIkguSS5JX0QyIiwgIkhfRDAiKQojSS1JCiMgY29udHJhc3QgPSBjKCJkaXNlYXNlX3RpbWUiLCAiSS5JX0QxIiwgIkhfRDAiKQojIGNvbnRyYXN0ID0gYygiZGlzZWFzZV90aW1lIiwgIkkuSV9EMyIsICJIX0QwIikKIyBjb250cmFzdCA9IGMoImRpc2Vhc2VfdGltZSIsICJJLklfRDUiLCAiSF9EMCIpCmBgYAoKKkhfQk5UX0kqIApgYGB7cn0KIyMjIyMjIyMjIEhfQk5UX0kKCiNIX0JOVF9JX0QxCmdzZTIwMTUzMF9IX0JOVF9JX0QxID0gcmVzdWx0cyhkZHMsIGNvbnRyYXN0ID0gYygiZGlzZWFzZV90aW1lIiwgIkguQk5ULklfRDEiLCAiSF9EMCIpKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICBhcnJhbmdlKHBhZGopICU+JSAKICBtdXRhdGUoY29uZGl0aW9uID0gIkgtQk5ULUkgKEQxKSIsCiAgICAgICAgIGRheSA9IDEsCiAgICAgICAgIHZhY2NpbmUgPSAiSC1CTlQtSSIsCiAgICAgICAgIGRpcmVjdGlvbiA9IGlmZWxzZShsb2cyRm9sZENoYW5nZSA+PSAxLCAiVVAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShsb2cyRm9sZENoYW5nZSA8PSAtMSwgIkRPV04iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkVVVFJBTCIpKSkgICU+JSAKICByb3duYW1lc190b19jb2x1bW4oImdlbmVzIikKCiNTYWx2YXIgdGFiZWxhCndyaXRlLmNzdihnc2UyMDE1MzBfSF9CTlRfSV9EMSwgZmlsZSA9ICJnc2UyMDE1MzBfSF9CTlRfSV9EMV9ERUdzX25vdGZpbHRlcmVkLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpCgojSF9CTlRfSV9EMwpnc2UyMDE1MzBfSF9CTlRfSV9EMyA9IHJlc3VsdHMoZGRzLCBjb250cmFzdCA9IGMoImRpc2Vhc2VfdGltZSIsICJILkJOVC5JX0QzIiwgIkhfRDAiKSkgJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JQogIGFycmFuZ2UocGFkaikgJT4lCiAgbXV0YXRlKGNvbmRpdGlvbiA9ICJILUJOVC1JIChEMykiLAogICAgICAgICBkYXkgPSAzLAogICAgICAgICB2YWNjaW5lID0gIkgtQk5ULUkiLAogICAgICAgICBkaXJlY3Rpb24gPSBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPj0gMSwgIlVQIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShsb2cyRm9sZENoYW5nZSA8PSAtMSwgIkRPV04iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORVVUUkFMIikpKSAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCJnZW5lcyIpCgojU2FsdmFyIHRhYmVsYQp3cml0ZS5jc3YoZ3NlMjAxNTMwX0hfQk5UX0lfRDMsIGZpbGUgPSAiZ3NlMjAxNTMwX0hfQk5UX0lfRDNfREVHcy5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQoKI0hfQk5UX0lfRDQKZ3NlMjAxNTMwX0hfQk5UX0lfRDQgPSByZXN1bHRzKGRkcywgY29udHJhc3QgPSBjKCJkaXNlYXNlX3RpbWUiLCAiSC5CTlQuSV9ENCIsICJIX0QwIikpICU+JQogIGFzLmRhdGEuZnJhbWUoKSAlPiUKICBmaWx0ZXIocGFkaiA8IDAuMDUpICU+JQogIGFycmFuZ2UocGFkaikgJT4lCiAgbXV0YXRlKGNvbmRpdGlvbiA9ICJILUJOVC1JIChENCkiLAogICAgICAgICBkYXkgPSA0LAogICAgICAgICB2YWNjaW5lID0gIkgtQk5ULUkiLAogICAgICAgICBkaXJlY3Rpb24gPSBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPj0gMSwgIlVQIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShsb2cyRm9sZENoYW5nZSA8PSAtMSwgIkRPV04iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORVVUUkFMIikpKSAgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigiZ2VuZXMiKQoKI1NhbHZhciB0YWJlbGEKd3JpdGUuY3N2KGdzZTIwMTUzMF9IX0JOVF9JX0Q0LCBmaWxlID0gImdzZTIwMTUzMF9IX0JOVF9JX0Q0X0RFR3MuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkKCmdzZTIwMTUzMF9IX0JOVF9JID0gYmluZF9yb3dzKGdzZTIwMTUzMF9IX0JOVF9JX0QxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3NlMjAxNTMwX0hfQk5UX0lfRDMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UyMDE1MzBfSF9CTlRfSV9ENCkKCndyaXRlLmNzdihnc2UyMDE1MzBfSF9CTlRfSSwgImdzZTIwMTUzMF9IX0JOVF9JLmNzdiIpCgpgYGAKCgoqSV9CTlRfSSogCmBgYHtyfQojIyMjIyMjIyMgSV9CTlRfSQoKI0QyCmdzZTIwMTUzMF9JX0JOVF9JX0QyID0gcmVzdWx0cyhkZHMsIGNvbnRyYXN0ID0gYygiZGlzZWFzZV90aW1lIiwgIkkuQk5ULklfRDIiLCAiSF9EMCIpKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICBmaWx0ZXIocGFkaiA8IDAuMDUpICU+JQogIGFycmFuZ2UocGFkaikgJT4lIAogIG11dGF0ZShjb25kaXRpb24gPSAiSS1CTlQtSSAoRDIpIiwKICAgICAgICAgZGF5ID0gMiwKICAgICAgICAgdmFjY2luZSA9ICJJLUJOVC1JIiwKICAgICAgICAgZGlyZWN0aW9uID0gaWZlbHNlKGxvZzJGb2xkQ2hhbmdlID49IDEsICJVUCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGxvZzJGb2xkQ2hhbmdlIDw9IC0xLCAiRE9XTiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORVVUUkFMIikpKSAgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigiZ2VuZXMiKQoKI1NhbHZhciB0YWJlbGEKd3JpdGUuY3N2KGdzZTIwMTUzMF9JX0JOVF9JX0QyLCBmaWxlID0gImdzZTIwMTUzMF9JX0JOVF9JX0QyX0RFR3MuY3N2IikKCgojRDUKZ3NlMjAxNTMwX0lfQk5UX0lfRDUgPSByZXN1bHRzKGRkcywgY29udHJhc3QgPSBjKCJkaXNlYXNlX3RpbWUiLCAiSS5CTlQuSV9ENSIsICJIX0QwIikpICU+JQogIGFzLmRhdGEuZnJhbWUoKSAlPiUKICBmaWx0ZXIocGFkaiA8IDAuMDUpICU+JQogIGFycmFuZ2UocGFkaikgJT4lCiAgbXV0YXRlKGNvbmRpdGlvbiA9ICJJLUJOVC1JIChENSkiLAogICAgICAgICBkYXkgPSA1LAogICAgICAgICB2YWNjaW5lID0gIkktQk5ULUkiLAogICAgICAgICBkaXJlY3Rpb24gPSBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPj0gMSwgIlVQIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShsb2cyRm9sZENoYW5nZSA8PSAtMSwgIkRPV04iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORVVUUkFMIikpKSAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCJnZW5lcyIpCgojU2FsdmFyIHRhYmVsYQp3cml0ZS5jc3YoZ3NlMjAxNTMwX0lfQk5UX0lfRDUsIGZpbGUgPSAiZ3NlMjAxNTMwX0hfQk5UX0lfRDVfREVHcy5jc3YiKQoKZ3NlMjAxNTMwX0lfQk5UX0kgPSBiaW5kX3Jvd3MoZ3NlMjAxNTMwX0lfQk5UX0lfRDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UyMDE1MzBfSV9CTlRfSV9ENSkKCndyaXRlLmNzdihnc2UyMDE1MzBfSV9CTlRfSSwgImdzZTIwMTUzMF9JX0JOVF9JLmNzdiIpCgpgYGAKCgoqSC1JKiAKYGBge3J9CiMjIyMjIyMjIyBILUkKCiNEMQpnc2UyMDE1MzBfSF9JX0QxID0gcmVzdWx0cyhkZHMsIGNvbnRyYXN0ID0gYygiZGlzZWFzZV90aW1lIiwgIkguSV9EMSIsICJIX0QwIikpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIGZpbHRlcihwYWRqIDwgMC4wNSkgJT4lCiAgYXJyYW5nZShwYWRqKSAlPiUgCiAgbXV0YXRlKGNvbmRpdGlvbiA9ICJILUkgKEQxKSIsCiAgICAgICAgIGRheSA9IDEsCiAgICAgICAgIHZhY2NpbmUgPSAiSC1JIiwKICAgICAgICAgZGlyZWN0aW9uID0gaWZlbHNlKGxvZzJGb2xkQ2hhbmdlID49IDEsICJVUCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGxvZzJGb2xkQ2hhbmdlIDw9IC0xLCAiRE9XTiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORVVUUkFMIikpKSAgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigiZ2VuZXMiKQoKI1NhbHZhciB0YWJlbGEKd3JpdGUuY3N2KGdzZTIwMTUzMF9IX0lfRDEsIGZpbGUgPSAiZ3NlMjAxNTMwX0hfSV9EMV9ERUdzLVBGLmNzdiIpCgoKI0Q1CmdzZTIwMTUzMF9IX0lfRDUgPSByZXN1bHRzKGRkcywgY29udHJhc3QgPSBjKCJkaXNlYXNlX3RpbWUiLCAiSS5CTlQuSV9ENSIsICJIX0QwIikpICU+JQogIGFzLmRhdGEuZnJhbWUoKSAlPiUKICBmaWx0ZXIocGFkaiA8IDAuMDUpICU+JQogIGFycmFuZ2UocGFkaikgJT4lCiAgbXV0YXRlKGNvbmRpdGlvbiA9ICJILUkgKEQ1KSIsCiAgICAgICAgIGRheSA9IDUsCiAgICAgICAgIHZhY2NpbmUgPSAiSC1JIiwKICAgICAgICAgZGlyZWN0aW9uID0gaWZlbHNlKGxvZzJGb2xkQ2hhbmdlID49IDEsICJVUCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPD0gLTEsICJET1dOIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkVVVFJBTCIpKSkgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigiZ2VuZXMiKQoKI1NhbHZhciB0YWJlbGEKd3JpdGUuY3N2KGdzZTIwMTUzMF9IX0lfRDUsIGZpbGUgPSAiZ3NlMjAxNTMwX0hfSV9ENV9ERUdzLVBGLmNzdiIpCgpnc2UyMDE1MzBfSF9JID0gYmluZF9yb3dzKGdzZTIwMTUzMF9JX0JOVF9JX0QyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3NlMjAxNTMwX0lfQk5UX0lfRDUpCgp3cml0ZS5jc3YoZ3NlMjAxNTMwX0hfSSwgImdzZTIwMTUzMF9IX0kuY3N2IikKCmBgYAoKKkgtSS1JKiAKYGBge3J9CgojIyMjIyMjIyMgSC1JLUkKI0QyCmdzZTIwMTUzMF9IX0lfSV9EMiA9IHJlc3VsdHMoZGRzLCBjb250cmFzdCA9IGMoImRpc2Vhc2VfdGltZSIsICJILkkuSV9EMiIsICJIX0QwIikpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIGZpbHRlcihwYWRqIDwgMC4wNSkgJT4lCiAgYXJyYW5nZShwYWRqKSAlPiUgCiAgbXV0YXRlKGNvbmRpdGlvbiA9ICJILUktSSAoRDIpIiwKICAgICAgICAgZGF5ID0gMiwKICAgICAgICAgdmFjY2luZSA9ICJILUktSSIsCiAgICAgICAgIGRpcmVjdGlvbiA9IGlmZWxzZShsb2cyRm9sZENoYW5nZSA+PSAxLCAiVVAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShsb2cyRm9sZENoYW5nZSA8PSAtMSwgIkRPV04iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkVVVFJBTCIpKSkgICU+JSAKICByb3duYW1lc190b19jb2x1bW4oImdlbmVzIikKCiNTYWx2YXIgdGFiZWxhCndyaXRlLmNzdihnc2UyMDE1MzBfSF9JX0lfRDIsIGZpbGUgPSAiZ3NlMjAxNTMwX0hfSV9JX0QyX0RFR3MtUEYuY3N2IikKCmBgYAoKKkktSSoKYGBge3J9CgojIyMjIyMjIyMgSS1JCiNEMQpnc2UyMDE1MzBfSV9JX0QxID0gcmVzdWx0cyhkZHMsIGNvbnRyYXN0ID0gYygiZGlzZWFzZV90aW1lIiwgIkkuSV9EMSIsICJIX0QwIikpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIGZpbHRlcihwYWRqIDwgMC4wNSkgJT4lCiAgYXJyYW5nZShwYWRqKSAlPiUgCiAgbXV0YXRlKGNvbmRpdGlvbiA9ICJJLUkgKEQxKSIsCiAgICAgICAgIGRheSA9IDEsCiAgICAgICAgIHZhY2NpbmUgPSAiSS1JIiwKICAgICAgICAgZGlyZWN0aW9uID0gaWZlbHNlKGxvZzJGb2xkQ2hhbmdlID49IDEsICJVUCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGxvZzJGb2xkQ2hhbmdlIDw9IC0xLCAiRE9XTiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORVVUUkFMIikpKSAgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigiZ2VuZXMiKQoKI1NhbHZhciB0YWJlbGEKd3JpdGUuY3N2KGdzZTIwMTUzMF9JX0lfRDEsIGZpbGUgPSAiZ3NlMjAxNTMwX0lfSV9EMV9ERUdzLVBGLmNzdiIpCgoKI0QzCmdzZTIwMTUzMF9JX0lfRDMgPSByZXN1bHRzKGRkcywgY29udHJhc3QgPSBjKCJkaXNlYXNlX3RpbWUiLCAiSS5JX0QzIiwgIkhfRDAiKSkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgZmlsdGVyKHBhZGogPCAwLjA1KSAlPiUKICBhcnJhbmdlKHBhZGopICU+JSAKICBtdXRhdGUoY29uZGl0aW9uID0gIkktSSAoRDMpIiwKICAgICAgICAgZGF5ID0gMywKICAgICAgICAgdmFjY2luZSA9ICJJLUkiLAogICAgICAgICBkaXJlY3Rpb24gPSBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPj0gMSwgIlVQIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPD0gLTEsICJET1dOIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FVVRSQUwiKSkpICAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCJnZW5lcyIpCgojU2FsdmFyIHRhYmVsYQp3cml0ZS5jc3YoZ3NlMjAxNTMwX0lfSV9EMywgZmlsZSA9ICJnc2UyMDE1MzBfSV9JX0QzX0RFR3MtUEYuY3N2IikKCgojRDUKZ3NlMjAxNTMwX0lfSV9ENSA9IHJlc3VsdHMoZGRzLCBjb250cmFzdCA9IGMoImRpc2Vhc2VfdGltZSIsICJJLklfRDUiLCAiSF9EMCIpKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICBmaWx0ZXIocGFkaiA8IDAuMDUpICU+JQogIGFycmFuZ2UocGFkaikgJT4lIAogIG11dGF0ZShjb25kaXRpb24gPSAiSS1JIChENSkiLAogICAgICAgICBkYXkgPSA1LAogICAgICAgICB2YWNjaW5lID0gIkktSSIsCiAgICAgICAgIGRpcmVjdGlvbiA9IGlmZWxzZShsb2cyRm9sZENoYW5nZSA+PSAxLCAiVVAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShsb2cyRm9sZENoYW5nZSA8PSAtMSwgIkRPV04iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkVVVFJBTCIpKSkgICU+JSAKICByb3duYW1lc190b19jb2x1bW4oImdlbmVzIikKCiNTYWx2YXIgdGFiZWxhCndyaXRlLmNzdihnc2UyMDE1MzBfSV9JX0Q1LCBmaWxlID0gImdzZTIwMTUzMF9JX0lfRDVfREVHcy1QRi5jc3YiKQoKZ3NlMjAxNTMwX0lfSSA9IGJpbmRfcm93cyhnc2UyMDE1MzBfSV9JX0QxLAogICAgICAgICAgICAgICAgICAgICAgICAgIGdzZTIwMTUzMF9JX0lfRDMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZ3NlMjAxNTMwX0lfSV9ENSkKCmBgYAoKVW5pciByYXcgZGF0YXNldHMgCmBgYHtyfQojIyMjIyMjIyMjIEdTRTIwMTUzMAoKZ3NlMjAxNTMwX0RFR3MgPSBiaW5kX3Jvd3MoZ3NlMjAxNTMwX0lfSSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3NlMjAxNTMwX0hfSV9JX0QyLAogICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UyMDE1MzBfSF9JLAogICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UyMDE1MzBfSV9CTlRfSSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3NlMjAxNTMwX0hfQk5UX0kpICU+JSAKICBtdXRhdGUoc3R1ZHkgPSAiR1NFMjAxNTMwIikKCiNTYWx2YXIKd3JpdGUuY3N2KGdzZTIwMTUzMF9ERUdzLCBmaWxlID0gImdzZTIwMTUzMF9ERUdzXzI3LTExLTIzLmNzdiIpCgpHU0UyMDE1MzBfbWV0YWRhdGFfY29uZGl0aW9ucyA9IGdzZTIwMTUzMF9ERUdzICU+JSAKICBzZWxlY3QoY29uZGl0aW9uOnZhY2NpbmUsIHN0dWR5KSAlPiUgCiAgZGlzdGluY3QoKQoKCiNBbm90YcOnw7Vlcwphbm5fdmFjY2luZXNfbG93ZXIgPSBhbm5fdmFjY2luZXMgJT4lIAogIGNsZWFuX25hbWVzKCkKCmFubl92YWNjaW5lc18yN18xMV8yMyA9IGJpbmRfcm93cyhhbm5fdmFjY2luZXNfbG93ZXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR1NFMjAxNTMwX21ldGFkYXRhX2NvbmRpdGlvbnMpCgojU2FsdmFyCndyaXRlLmNzdihhbm5fdmFjY2luZXNfMjdfMTFfMjMsIGZpbGUgPSAnYW5uX3ZhY2NpbmVzXzI3XzExXzIzLmNzdicpCgoKYGBgCgoKCgoKCiMjIEdTRTE4OTAzOQoKYGBge3J9CiMjI0RFU0VRMiAtIFBGIHZlcnN1cyBBWiwgUEYgZW0gZGlmZXJlbnRlcyB0ZW1wb3MsIEFaIGVtIGRpZmVyZW50ZXMgdGVtcG9zCgojIyMjRGVmaW5pbmRvIGRlc2lnbgoKIyMjIyMjIFBhZHJvbml6ZSBhcyB2YXJpw6F2ZWlzIApjb3VudERhdGEgPC0gZ3NlMTg5MDM5X2NvdW50c19yZWFkeQpjb2xEYXRhIDwtIEdTRTE4OTAzOV9tZXRhZGF0YSAlPiUKICBtdXRhdGUoZGlzZWFzZV92YWMgPSBpZmVsc2UoZGlzZWFzZV92YWMgPT0gIkkiLCAiSC1JIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGRpc2Vhc2VfdmFjID09ICJCTlQtSSIsICJILUJOVC1JIiwgZGlzZWFzZV92YWMpKSwKICAgICAgICAgZGlzZWFzZV92YWNfc2V2ZXJpdHlfdGltZSA9IHBhc3RlMChkaXNlYXNlX3ZhYywgIl8iLCBzZXZlcml0eSwgIl9EIiwgdGltZXBvaW50X2RheSksCiAgICAgICAgIGRpc2Vhc2VfdmFjX3NldmVyaXR5X3RpbWUgPSBmYWN0b3IoZGlzZWFzZV92YWNfc2V2ZXJpdHlfdGltZSkpICU+JSAKICBzZWxlY3Qoc3ViamVjdF9pZCwgZXZlcnl0aGluZygpKQoKCiMjIyMjIyBDcmllIG8gb2JqZXRvIERFU2VxRGF0YVNldCAjIyMjIyMKZGRzIDwtIERFU2VxRGF0YVNldEZyb21NYXRyaXgoY291bnREYXRhID0gY291bnREYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sRGF0YSA9IGNvbERhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSB+IGRpc2Vhc2VfdmFjX3NldmVyaXR5X3RpbWUpCgojIyMjIyMgUHLDqS1maWx0cmFnZW0gIyMjIyMjCmtlZXAgPC0gcm93U3Vtcyhjb3VudHMoZGRzKSkgPj0gMTAKZGRzIDwtIGRkc1trZWVwLF0KCiMjIyMjIyBFeGVjdXRhciBERVNlcSAjIyMjIyMKCiNNw6l0b2RvIFdhbGQKZGRzIDwtIERFU2VxKGRkcykKCiNTYWx2YXIKd3JpdGVfcmRzKGRkcyxmaWxlPSJnc2UxODkwMzlfZGRzX0RFU2VxMl9XYWxkX2Rpc2Vhc2VfdmFjX3NldmVyaXR5X3RpbWUucmRzIikKCiMjIyMjIyBPYnRlciBjb21wYXJhw6fDtWVzIHJlYWxpemFkYXMgIyMjIyMjCnJlc3VsdHNOYW1lcyhkZHMpCgojIyMjIyMgT2J0ZW5kbyBvcyBERUdzIHRvdGFpcyAjIyMjIyMKcmVzIDwtIHJlc3VsdHMoZGRzKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICBmaWx0ZXIocHZhbHVlIDwgMC4wNSkKCiNTYWx2YXIgdGFiZWxhCndyaXRlLmNzdihyZXMsIGZpbGUgPSAiZ3NlMTg5MDM5X2Rkc19ERVNlcTJfV2FsZF9kaXNlYXNlX3ZhY19zZXZlcml0eV90aW1lX0FMTERFR1MucmRzIikKCmBgYAoKKkNvbXBhcmFuZG8gdGVtcG9zIGUgY29uZGnDp8O1ZXMqCgpOZXN0YSBjb21wYXJhw6fDo28sIHPDo28gZW5jb250cmFkYXMgREVHcyBkZSBjYWRhIHZhY2luYSBpbmRpdmlkdWFsIG5vcyBkaWZlcmVudGVzIHRlbXBvcy4gUGFyYSBjb21wYXJhciB1bWEgdmFjaW5hIGNvbSBhIG91dHJhIGVtIGRpZmVyZW50ZXMgdGVtcG9zLCDDqSBuZWNlc3PDoXJpbyB1c2FyIG9zIGFyZ3VtZW50b3MgImNvbnRyYXN0IiBvdSAibmFtZSIuCgpgYGB7cn0KCiMjIEgtSQojIE1PREVSQVRFCiMgY29udHJhc3QgPSBjKCJkaXNlYXNlX3ZhY19zZXZlcml0eV90aW1lIiwgIkguSV9tb2RlcmF0ZV9EMTAiLCAiSF9uYWl2ZV92YWNfRDAiKQojIGNvbnRyYXN0ID0gYygiZGlzZWFzZV92YWNfc2V2ZXJpdHlfdGltZSIsICJILklfbW9kZXJhdGVfRDI2IiwgIkhfbmFpdmVfdmFjX0QwIikKIyBjb250cmFzdCA9IGMoImRpc2Vhc2VfdmFjX3NldmVyaXR5X3RpbWUiLCAiSC5JX21vZGVyYXRlX0Q1MSIsICJIX25haXZlX3ZhY19EMCIpCgojIFNFVkVSRQojIGNvbnRyYXN0ID0gYygiZGlzZWFzZV92YWNfc2V2ZXJpdHlfdGltZSIsICJILklfc2V2ZXJlX0QxMCIsICJIX25haXZlX3ZhY19EMCIpCiMgY29udHJhc3QgPSBjKCJkaXNlYXNlX3ZhY19zZXZlcml0eV90aW1lIiwgIkguSV9zZXZlcmVfRDI2IiwgIkhfbmFpdmVfdmFjX0QwIikKIyBjb250cmFzdCA9IGMoImRpc2Vhc2VfdmFjX3NldmVyaXR5X3RpbWUiLCAiSC5JX3NldmVyZV9ENTEiLCAiSF9uYWl2ZV92YWNfRDAiKQoKCiMjIEgtQk5ULUkKIyBNSUxECiMgY29udHJhc3QgPSBjKCJkaXNlYXNlX3ZhY19zZXZlcml0eV90aW1lIiwgIkguQk5ULklfbWlsZF9EMTAiLCAiSF9uYWl2ZV92YWNfRDAiKQojIGNvbnRyYXN0ID0gYygiZGlzZWFzZV92YWNfc2V2ZXJpdHlfdGltZSIsICJILkJOVC5JX21pbGRfRDI2IiwgIkhfbmFpdmVfdmFjX0QwIikKCiMgU0VWRVJFCiMgY29udHJhc3QgPSBjKCJkaXNlYXNlX3ZhY19zZXZlcml0eV90aW1lIiwgIkguQk5ULklfc2V2ZXJlX0QxMCIsICJIX25haXZlX3ZhY19EMCIpCiMgY29udHJhc3QgPSBjKCJkaXNlYXNlX3ZhY19zZXZlcml0eV90aW1lIiwgIkguQk5ULklfc2V2ZXJlX0QyNiIsICJIX25haXZlX3ZhY19EMCIpCgojIyBCTlQtSS1CTlQKIyBjb250cmFzdCA9IGMoImRpc2Vhc2VfdmFjX3NldmVyaXR5X3RpbWUiLCAiQk5ULkkuQk5UX3NldmVyZV9ENTEiLCAiSF9uYWl2ZV92YWNfRDAiKQpjb250cmFzdCA9IGMoImRpc2Vhc2VfdmFjX3NldmVyaXR5X3RpbWUiLCAiQk5ULkkuQk5UX21pbGRfRDUxIiwgIkhfbmFpdmVfdmFjX0QwIikgKG5hbyBmb2kgPz8/KQoKYGBgCgoqSF9JKiAKYGBge3J9CiMjIyMjIyMjIyBIX0kKCiNIX0lfRDEwCmdzZTE4OTAzOV9IX0lfbW9kZXJhdGVfRDEwID0gcmVzdWx0cyhkZHMsIGNvbnRyYXN0ID0gYygiZGlzZWFzZV92YWNfc2V2ZXJpdHlfdGltZSIsICJILklfbW9kZXJhdGVfRDEwIiwgIkhfbmFpdmVfdmFjX0QwIikpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIGZpbHRlcihwYWRqIDwgMC4wNSkgJT4lCiAgYXJyYW5nZShwYWRqKSAlPiUgCiAgbXV0YXRlKGNvbmRpdGlvbiA9ICJILUkgKEQxMCwgbW9kZXJhdGUpIiwKICAgICAgICAgZGF5ID0gMTAsCiAgICAgICAgIHZhY2NpbmUgPSAiSC1JIiwKICAgICAgICAgc2V2ZXJpdHkgPSAibW9kZXJhdGUiLAogICAgICAgICBkaXJlY3Rpb24gPSBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPj0gMSwgIlVQIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPD0gLTEsICJET1dOIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FVVRSQUwiKSkpICAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCJnZW5lcyIpCgojU2FsdmFyIHRhYmVsYQp3cml0ZS5jc3YoZ3NlMTg5MDM5X0hfSV9tb2RlcmF0ZV9EMTAsIGZpbGUgPSAiZ3NlMTg5MDM5X0hfSV9tb2RlcmF0ZV9EMTBfREVHcy5jc3YiKQoKI0hfSV9EMjYKZ3NlMTg5MDM5X0hfSV9tb2RlcmF0ZV9EMjYgPSByZXN1bHRzKGRkcywgY29udHJhc3QgPSBjKCJkaXNlYXNlX3ZhY19zZXZlcml0eV90aW1lIiwgIkguSV9tb2RlcmF0ZV9EMjYiLCAiSF9uYWl2ZV92YWNfRDAiKSkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgZmlsdGVyKHBhZGogPCAwLjA1KSAlPiUKICBhcnJhbmdlKHBhZGopICU+JSAKICBtdXRhdGUoY29uZGl0aW9uID0gIkgtSSAoRDI2LCBtb2RlcmF0ZSkiLAogICAgICAgICBkYXkgPSAyNiwKICAgICAgICAgc2V2ZXJpdHkgPSAibW9kZXJhdGUiLAogICAgICAgICB2YWNjaW5lID0gIkgtSSIsCiAgICAgICAgIGRpcmVjdGlvbiA9IGlmZWxzZShsb2cyRm9sZENoYW5nZSA+PSAxLCAiVVAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShsb2cyRm9sZENoYW5nZSA8PSAtMSwgIkRPV04iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkVVVFJBTCIpKSkgICU+JSAKICByb3duYW1lc190b19jb2x1bW4oImdlbmVzIikKCiNTYWx2YXIgdGFiZWxhCndyaXRlLmNzdihnc2UxODkwMzlfSF9JX21vZGVyYXRlX0QyNiwgZmlsZSA9ICJnc2UxODkwMzlfSF9JX21vZGVyYXRlX0QyNl9ERUdzLmNzdiIpCgojSF9JX0Q1MQpnc2UxODkwMzlfSF9JX21vZGVyYXRlX0Q1MSA9IHJlc3VsdHMoZGRzLCBjb250cmFzdCA9IGMoImRpc2Vhc2VfdmFjX3NldmVyaXR5X3RpbWUiLCAiSC5JX21vZGVyYXRlX0Q1MSIsICJIX25haXZlX3ZhY19EMCIpKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICBmaWx0ZXIocGFkaiA8IDAuMDUpICU+JQogIGFycmFuZ2UocGFkaikgJT4lIAogIG11dGF0ZShjb25kaXRpb24gPSAiSC1JIChENTEsIG1vZGVyYXRlKSIsCiAgICAgICAgIGRheSA9IDUxLAogICAgICAgICB2YWNjaW5lID0gIkgtSSIsCiAgICAgICAgIHNldmVyaXR5ID0gIm1vZGVyYXRlIiwKICAgICAgICAgZGlyZWN0aW9uID0gaWZlbHNlKGxvZzJGb2xkQ2hhbmdlID49IDEsICJVUCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGxvZzJGb2xkQ2hhbmdlIDw9IC0xLCAiRE9XTiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORVVUUkFMIikpKSAgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigiZ2VuZXMiKQoKI1NhbHZhciB0YWJlbGEKd3JpdGUuY3N2KGdzZTE4OTAzOV9IX0lfbW9kZXJhdGVfRDUxLCBmaWxlID0gImdzZTE4OTAzOV9IX0lfbW9kZXJhdGVfRDUxX0RFR3MuY3N2IikKCiNIX0lfc2V2ZXJlX0QxMApnc2UxODkwMzlfSF9JX3NldmVyZV9EMTAgPSByZXN1bHRzKGRkcywgY29udHJhc3QgPSBjKCJkaXNlYXNlX3ZhY19zZXZlcml0eV90aW1lIiwgIkguSV9zZXZlcmVfRDEwIiwgIkhfbmFpdmVfdmFjX0QwIikpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIGZpbHRlcihwYWRqIDwgMC4wNSkgJT4lCiAgYXJyYW5nZShwYWRqKSAlPiUgCiAgbXV0YXRlKGNvbmRpdGlvbiA9ICJILUkgKEQxMCwgc2V2ZXJlKSIsCiAgICAgICAgIGRheSA9IDEwLAogICAgICAgICB2YWNjaW5lID0gIkgtSSIsCiAgICAgICAgIHNldmVyaXR5ID0gInNldmVyZSIsCiAgICAgICAgIGRpcmVjdGlvbiA9IGlmZWxzZShsb2cyRm9sZENoYW5nZSA+PSAxLCAiVVAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShsb2cyRm9sZENoYW5nZSA8PSAtMSwgIkRPV04iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkVVVFJBTCIpKSkgICU+JSAKICByb3duYW1lc190b19jb2x1bW4oImdlbmVzIikKCiNTYWx2YXIgdGFiZWxhCndyaXRlLmNzdihnc2UxODkwMzlfSF9JX3NldmVyZV9EMTAsIGZpbGUgPSAiZ3NlMTg5MDM5X0hfSV9zZXZlcmVfRDEwX0RFR3MuY3N2IikKCgoKI0hfSV9zZXZlcmVfRDI2CmdzZTE4OTAzOV9IX0lfc2V2ZXJlX0QyNiA9IHJlc3VsdHMoZGRzLCBjb250cmFzdCA9IGMoImRpc2Vhc2VfdmFjX3NldmVyaXR5X3RpbWUiLCAiSC5JX3NldmVyZV9EMjYiLCAiSF9uYWl2ZV92YWNfRDAiKSkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgZmlsdGVyKHBhZGogPCAwLjA1KSAlPiUKICBhcnJhbmdlKHBhZGopICU+JSAKICBtdXRhdGUoY29uZGl0aW9uID0gIkgtSSAoRDI2LCBzZXZlcmUpIiwKICAgICAgICAgZGF5ID0gMjYsCiAgICAgICAgIHZhY2NpbmUgPSAiSC1JIiwKICAgICAgICAgc2V2ZXJpdHkgPSAic2V2ZXJlIiwKICAgICAgICAgZGlyZWN0aW9uID0gaWZlbHNlKGxvZzJGb2xkQ2hhbmdlID49IDEsICJVUCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGxvZzJGb2xkQ2hhbmdlIDw9IC0xLCAiRE9XTiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORVVUUkFMIikpKSAgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigiZ2VuZXMiKQoKI1NhbHZhciB0YWJlbGEKd3JpdGUuY3N2KGdzZTE4OTAzOV9IX0lfc2V2ZXJlX0QyNiwgZmlsZSA9ICJnc2UxODkwMzlfSF9JX3NldmVyZV9EMjZfREVHcy5jc3YiKQoKI0hfSV9zZXZlcmVfRDUxCmdzZTE4OTAzOV9IX0lfc2V2ZXJlX0Q1MSA9IHJlc3VsdHMoZGRzLCBjb250cmFzdCA9IGMoImRpc2Vhc2VfdmFjX3NldmVyaXR5X3RpbWUiLCAiSC5JX3NldmVyZV9ENTEiLCAiSF9uYWl2ZV92YWNfRDAiKSkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgZmlsdGVyKHBhZGogPCAwLjA1KSAlPiUKICBhcnJhbmdlKHBhZGopICU+JSAKICBtdXRhdGUoY29uZGl0aW9uID0gIkgtSSAoRDUxLCBzZXZlcmUpIiwKICAgICAgICAgZGF5ID0gNTEsCiAgICAgICAgIHZhY2NpbmUgPSAiSC1JIiwKICAgICAgICAgc2V2ZXJpdHkgPSAic2V2ZXJlIiwKICAgICAgICAgZGlyZWN0aW9uID0gaWZlbHNlKGxvZzJGb2xkQ2hhbmdlID49IDEsICJVUCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGxvZzJGb2xkQ2hhbmdlIDw9IC0xLCAiRE9XTiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORVVUUkFMIikpKSAgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigiZ2VuZXMiKQoKI1NhbHZhciB0YWJlbGEKd3JpdGUuY3N2KGdzZTE4OTAzOV9IX0lfc2V2ZXJlX0Q1MSwgZmlsZSA9ICJnc2UxODkwMzlfSF9JX3NldmVyZV9ENTFfREVHcy5jc3YiKQoKZ3NlMTg5MDM5X0hfSSA9IGJpbmRfcm93cyhnc2UxODkwMzlfSF9JX21vZGVyYXRlX0QxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UxODkwMzlfSF9JX3NldmVyZV9EMTAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UxODkwMzlfSF9JX21vZGVyYXRlX0QyNiwKICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UxODkwMzlfSF9JX3NldmVyZV9EMjYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UxODkwMzlfSF9JX21vZGVyYXRlX0Q1MSwKICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UxODkwMzlfSF9JX3NldmVyZV9ENTEpCgp3cml0ZS5jc3YoZ3NlMTg5MDM5X0hfSSwgImdzZTE4OTAzOV9IX0lfREVHUy5jc3YiKQoKYGBgCgoKKkhfQk5UX0kqIApgYGB7cn0KIyMjIyMjIyMjIEgtQk5ULUkKCiNIX0JOVC1JCgojTUlMRApnc2UxODkwMzlfSF9CTlRfSV9taWxkX0QxMCA9IHJlc3VsdHMoZGRzLCBjb250cmFzdCA9IGMoImRpc2Vhc2VfdmFjX3NldmVyaXR5X3RpbWUiLCAiSC5CTlQuSV9taWxkX0QxMCIsICJIX25haXZlX3ZhY19EMCIpKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICBmaWx0ZXIocGFkaiA8IDAuMDUpICU+JQogIGFycmFuZ2UocGFkaikgJT4lIAogIG11dGF0ZShjb25kaXRpb24gPSAiSC1CTlQtSSAoRDEwLCBtaWxkKSIsCiAgICAgICAgIGRheSA9IDEwLAogICAgICAgICB2YWNjaW5lID0gIkgtQk5ULUkiLAogICAgICAgICBzZXZlcml0eSA9ICJtaWxkIiwKICAgICAgICAgZGlyZWN0aW9uID0gaWZlbHNlKGxvZzJGb2xkQ2hhbmdlID49IDEsICJVUCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGxvZzJGb2xkQ2hhbmdlIDw9IC0xLCAiRE9XTiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORVVUUkFMIikpKSAgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigiZ2VuZXMiKQoKI1NhbHZhciB0YWJlbGEKd3JpdGUuY3N2KGdzZTE4OTAzOV9IX0JOVF9JX21pbGRfRDEwLCBmaWxlID0gImdzZTE4OTAzOV9IX0JOVF9JX21pbGRfRDEwX0RFR3MuY3N2IikKCgpnc2UxODkwMzlfSF9CTlRfSV9taWxkX0QyNiA9IHJlc3VsdHMoZGRzLCBjb250cmFzdCA9IGMoImRpc2Vhc2VfdmFjX3NldmVyaXR5X3RpbWUiLCAiSC5CTlQuSV9taWxkX0QyNiIsICJIX25haXZlX3ZhY19EMCIpKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICBmaWx0ZXIocGFkaiA8IDAuMDUpICU+JQogIGFycmFuZ2UocGFkaikgJT4lIAogIG11dGF0ZShjb25kaXRpb24gPSAiSC1CTlQtSSAoRDI2LCBtaWxkKSIsCiAgICAgICAgIGRheSA9IDI2LAogICAgICAgICB2YWNjaW5lID0gIkgtQk5ULUkiLAogICAgICAgICBzZXZlcml0eSA9ICJtaWxkIiwKICAgICAgICAgZGlyZWN0aW9uID0gaWZlbHNlKGxvZzJGb2xkQ2hhbmdlID49IDEsICJVUCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGxvZzJGb2xkQ2hhbmdlIDw9IC0xLCAiRE9XTiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORVVUUkFMIikpKSAgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigiZ2VuZXMiKQoKI1NhbHZhciB0YWJlbGEKd3JpdGUuY3N2KGdzZTE4OTAzOV9IX0JOVF9JX21pbGRfRDI2LCBmaWxlID0gImdzZTE4OTAzOV9IX0JOVF9JX21pbGRfRDI2X0RFR3MuY3N2IikKCgojU0VWRVJFCgpnc2UxODkwMzlfSF9CTlRfSV9zZXZlcmVfRDEwID0gcmVzdWx0cyhkZHMsIGNvbnRyYXN0ID0gYygiZGlzZWFzZV92YWNfc2V2ZXJpdHlfdGltZSIsICJILkJOVC5JX3NldmVyZV9EMTAiLCAiSF9uYWl2ZV92YWNfRDAiKSkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgZmlsdGVyKHBhZGogPCAwLjA1KSAlPiUKICBhcnJhbmdlKHBhZGopICU+JSAKICBtdXRhdGUoY29uZGl0aW9uID0gIkgtQk5ULUkgKEQxMCwgc2V2ZXJlKSIsCiAgICAgICAgIGRheSA9IDEwLAogICAgICAgICB2YWNjaW5lID0gIkgtQk5ULUkiLAogICAgICAgICBzZXZlcml0eSA9ICJzZXZlcmUiLAogICAgICAgICBkaXJlY3Rpb24gPSBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPj0gMSwgIlVQIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPD0gLTEsICJET1dOIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FVVRSQUwiKSkpICAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCJnZW5lcyIpCgojU2FsdmFyIHRhYmVsYQp3cml0ZS5jc3YoZ3NlMTg5MDM5X0hfQk5UX0lfc2V2ZXJlX0QxMCwgZmlsZSA9ICJnc2UxODkwMzlfSF9CTlRfSV9zZXZlcmVfRDEwX0RFR3MuY3N2IikKCgpnc2UxODkwMzlfSF9CTlRfSV9zZXZlcmVfRDI2ID0gcmVzdWx0cyhkZHMsIGNvbnRyYXN0ID0gYygiZGlzZWFzZV92YWNfc2V2ZXJpdHlfdGltZSIsICJILkJOVC5JX3NldmVyZV9EMjYiLCAiSF9uYWl2ZV92YWNfRDAiKSkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgZmlsdGVyKHBhZGogPCAwLjA1KSAlPiUKICBhcnJhbmdlKHBhZGopICU+JSAKICBtdXRhdGUoY29uZGl0aW9uID0gIkgtQk5ULUkgKEQyNiwgc2V2ZXJlKSIsCiAgICAgICAgIGRheSA9IDI2LAogICAgICAgICB2YWNjaW5lID0gIkgtQk5ULUkiLAogICAgICAgICBzZXZlcml0eSA9ICJzZXZlcmUiLAogICAgICAgICBkaXJlY3Rpb24gPSBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPj0gMSwgIlVQIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPD0gLTEsICJET1dOIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FVVRSQUwiKSkpICAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCJnZW5lcyIpCgojU2FsdmFyIHRhYmVsYQp3cml0ZS5jc3YoZ3NlMTg5MDM5X0hfQk5UX0lfc2V2ZXJlX0QyNiwgZmlsZSA9ICJnc2UxODkwMzlfSF9CTlRfSV9zZXZlcmVfRDI2X0RFR3MuY3N2IikKCiNVTklSCmdzZTE4OTAzOV9IX0JOVF9JID0gYmluZF9yb3dzKGdzZTE4OTAzOV9IX0JOVF9JX21pbGRfRDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UxODkwMzlfSF9CTlRfSV9zZXZlcmVfRDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UxODkwMzlfSF9CTlRfSV9taWxkX0QyNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3NlMTg5MDM5X0hfQk5UX0lfc2V2ZXJlX0QyNikKI1NhbHZhcgp3cml0ZS5jc3YoZ3NlMTg5MDM5X0hfQk5UX0ksIGZpbGUgPSAiZ3NlMTg5MDM5X0hfQk5UX0lfREVHUy5jc3YiKQoKYGBgCgoKKkJOVC1JLUJOVCoKYGBge3J9CiMjIyMjIyMjIyBCTlQtSS1CTlQJCgojIEQ1MQpnc2UxODkwMzlfQk5UX0lfQk5UX3NldmVyZV9ENTEgPSByZXN1bHRzKGRkcywgY29udHJhc3QgPSBjKCJkaXNlYXNlX3ZhY19zZXZlcml0eV90aW1lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJOVC5JLkJOVF9zZXZlcmVfRDUxIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJIX25haXZlX3ZhY19EMCIpKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICBmaWx0ZXIocGFkaiA8IDAuMDUpICU+JQogIGFycmFuZ2UocGFkaikgJT4lIAogIG11dGF0ZShjb25kaXRpb24gPSAiQk5ULUktQk5UIChENTEsIHNldmVyZSkiLAogICAgICAgICBkYXkgPSA1MSwKICAgICAgICAgdmFjY2luZSA9ICJCTlQtSS1CTlQiLAogICAgICAgICBzZXZlcml0eSA9ICJzZXZlcmUiLAogICAgICAgICBkaXJlY3Rpb24gPSBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPj0gMSwgIlVQIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPD0gLTEsICJET1dOIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FVVRSQUwiKSkpICAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCJnZW5lcyIpCgojU2FsdmFyIHRhYmVsYQp3cml0ZS5jc3YoZ3NlMTg5MDM5X0JOVF9JX0JOVF9zZXZlcmVfRDUxLCBmaWxlID0gImdzZTE4OTAzOV9CTlRfSV9CTlRfc2V2ZXJlX0Q1MV9ERUdzLmNzdiIpCgoKI0FxdWkgdGl2ZSBkZSB1c2FyIG8gYXJndW1lbnRvIG5hbWUsIHBvaXMgY29udHJhc3QgbsOjbyBlc3RhdmEgZnVuY2lvbmFuZG8gKD8pCmdzZTE4OTAzOV9CTlRfSV9CTlRfbWlsZF9ENTEgPSByZXN1bHRzKGRkcywgbmFtZT0gImRpc2Vhc2VfdmFjX3NldmVyaXR5X3RpbWVfSF9uYWl2ZV92YWNfRDBfdnNfQk5ULkkuQk5UX21pbGRfRDUxIikgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgZmlsdGVyKHBhZGogPCAwLjA1KSAlPiUKICBtdXRhdGUobG9nMkZvbGRDaGFuZ2UgPSBpZmVsc2UobG9nMkZvbGRDaGFuZ2UgPiAwLCAtbG9nMkZvbGRDaGFuZ2UsIGFicyhsb2cyRm9sZENoYW5nZSkpKSAlPiUgCiAgYXJyYW5nZShwYWRqKSAlPiUgCiAgbXV0YXRlKGNvbmRpdGlvbiA9ICJCTlQtSS1CTlQgKEQ1MSwgbWlsZCkiLAogICAgICAgICBkYXkgPSA1MSwKICAgICAgICAgdmFjY2luZSA9ICJCTlQtSS1CTlQiLAogICAgICAgICBzZXZlcml0eSA9ICJtaWxkIiwKICAgICAgICAgZGlyZWN0aW9uID0gaWZlbHNlKGxvZzJGb2xkQ2hhbmdlID49IDEsICJVUCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGxvZzJGb2xkQ2hhbmdlIDw9IC0xLCAiRE9XTiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORVVUUkFMIikpKSAgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigiZ2VuZXMiKSAKCiNTYWx2YXIgdGFiZWxhCndyaXRlLmNzdihnc2UxODkwMzlfQk5UX0lfQk5UX21pbGRfRDUxLCBmaWxlID0gImdzZTE4OTAzOV9CTlRfSV9CTlRfbWlsZF9ENTFfREVHcy5jc3YiKQoKI1VuaXIKZ3NlMTg5MDM5X0JOVF9JX0JOVCA9IGJpbmRfcm93cyhnc2UxODkwMzlfQk5UX0lfQk5UX21pbGRfRDUxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdzZTE4OTAzOV9CTlRfSV9CTlRfc2V2ZXJlX0Q1MSkKCgp3cml0ZS5jc3YoZ3NlMTg5MDM5X0JOVF9JX0JOVCwgZmlsZSA9ICJnc2UxODkwMzlfQk5UX0lfQk5UX0RFR1MuY3N2IikKCmBgYAoKKlVOSVIqCmBgYHtyfQpnc2UxODkwMzlfREVHcyA9IGJpbmRfcm93cyhnc2UxODkwMzlfQk5UX0lfQk5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UxODkwMzlfSF9JLAogICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UxODkwMzlfSF9CTlRfSSkgJT4lIAogIG11dGF0ZShzdHVkeSA9ICJHU0UxODkwMzkiKQoKCgojIyMjIyBUT0RBUyBBUyBERUdTCgpnc2VfMjAxNTMwXzE4OTAzOSA9IGJpbmRfcm93cyhnc2UyMDE1MzBfREVHcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3NlMTg5MDM5X0RFR3MpICU+JSAKICBzZWxlY3QoZ2VuZXM6Y29uZGl0aW9uLCBkaXJlY3Rpb24pICU+JSAKICBtZXJnZShhbm5fdmFjY2luZXMsIGJ5ID0gImNvbmRpdGlvbiIsIGFsbC55ID0gRikgJT4lIAogIGNsZWFuX25hbWVzKCkKCmRlZ3NfYWxsc3R1ZGllc191cGRvd25fcF8wNSA9IGRlZ3NfYWxsc3R1ZGllc191cGRvd25fcF8wNSAlPiUgCiAgY2xlYW5fbmFtZXMoKSAlPiUgCiAgc2VsZWN0KGdlbmVzOmRpcmVjdGlvbiwgLXZhY2NpbmUsIC1nc2VfaWQpICU+JSAKICBtZXJnZShhbm5fdmFjY2luZXMsIGJ5ID0gImNvbmRpdGlvbiIsIGFsbC55ID0gRikgJT4lIAogIHNlbGVjdCgtcGFydGljaXBhbnRzKQoKCmFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkID0gYmluZF9yb3dzKGRlZ3NfYWxsc3R1ZGllc191cGRvd25fcF8wNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3NlXzIwMTUzMF8xODkwMzkpICU+JSAKICBtdXRhdGVfYWxsKH4gcmVwbGFjZSguLCBpcy5uYSguKSwgIk5BIikpICU+JSAKICBtdXRhdGUocmVnaW1lbiA9IGNhc2Vfd2hlbigKcmVnaW1lbiA9PSAiQk5ULUktQk5UIiB+ICJWLUktViIsCnJlZ2ltZW4gPT0gIkgtQk5ULUkiIH4gIlYtSSIsCnJlZ2ltZW4gPT0gIlZBQy1JIiB+ICJWLUkiLApyZWdpbWVuID09ICJJLVZBQy1JIiB+ICJJLVYtSSIsCnJlZ2ltZW4gPT0gIkgtVi1JIiB+ICJWLUkiLApyZWdpbWVuID09ICJILUktSSIgfiAiSS1JIiwKcmVnaW1lbiA9PSAiSC1JIiB+ICJJIiwKVFJVRSB+IGFzLmNoYXJhY3RlcihyZWdpbWVuKSkpCgojU2FsdmFyCndyaXRlLmNzdihnc2VfMjAxNTMwXzE4OTAzOSwgZmlsZSA9ICJnc2VfMjAxNTMwXzE4OTAzOV9ERUdzXzI3LTExLTIzLmNzdiIpCgojU2FsdmFyCndyaXRlLmNzdihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgZmlsZSA9ICdhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZF8yNy0xMS0yMy5jc3YnKQpgYGAKCkNvbXBhcmFyIG51bWVybyBkZSBwYXJ0aWNpcGFudGVzCmBgYHtyfQoKYW5uX3ZhY2NpbmVzID0gYW5uX3ZhY2NpbmVzXzI5XzExXzIzICU+JSAKICBjbGVhbl9uYW1lcygpICU+JSAKICBtdXRhdGUoY29uZGl0aW9uID0gZmFjdG9yKGNvbmRpdGlvbiwgbGV2ZWxzID0gcmV2KGNvbmRpdGlvbikpKQoKCnBsb3QgPSBhbm5fdmFjY2luZXMgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeCA9IGNvbmRpdGlvbiwgCiAgICAgIHkgPSBwYXJ0aWNpcGFudHMsIAogICAgICBmaWxsID0gZ3NlX2lkKSArCiAgZ2VvbV9jb2woKSArCiAgbGFicyh0aXRsZSA9ICJQYXJ0aWNpcGFudHMgYnkgY29uZGl0aW9uIikgKwogIGNvb3JkX2ZsaXAoKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB5bGltKDAsIDcwKSArCiAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKCJHU0UxOTk3NTAiID0gIiM4MGZmZGIiLAogICAgICAgICAgICAgICAiR1NFMjAxNTMzIiA9ICIjNWU2MGNlIiwgCiAgICAgICAgICAgICAgICJHU0UyMDE1MzAiID0gIiM3NDAwYjgiLAogICAgICAgICAgICAgICAiR1NFMjA2MDIzIiA9ICIjNDM2MWVlIiwKICAgICAgICAgICAgICAgIkdTRTE4OTAzOSIgPSAiIzQ4YmZlMyIpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhcnRpY2lwYW50cywgeSA9IHBhcnRpY2lwYW50cyksIAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC45KSwgCiAgICAgICAgICAgIHZqdXN0ID0gMC41LCAKICAgICAgICAgICAgaGp1c3QgPSAtMC4yLCAKICAgICAgICAgICAgc2l6ZSA9IDMpCgpnZ3NhdmUocGxvdCwgZmlsZSA9ICJTYW1wbGVzX3Blcl9jb25kaXRpb25fYnlfR1NFLnBuZyIsIHdpZHRoID0gNiwgaGVpZ2h0ID0gMTApCmdnc2F2ZShwbG90LCBmaWxlID0gIlNhbXBsZXNfcGVyX2NvbmRpdGlvbl9ieV9HU0VfMi5wbmciLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2KQoKYGBgCgpDb21wYXJhciBzZXhvCmBgYHtyfQoKZXNxdWlzc2VyKERlbW9ncmFwaGljcykKClNleCA9IERlbW9ncmFwaGljcyAlPiUKIGZpbHRlcighKFN1YiAlaW4lICJNZWFuIikpICU+JQogZ2dwbG90KCkgKwogIGFlcyh4ID0gU3R1ZHksIHkgPSBWYWx1ZSwgZmlsbCA9IFN1YikgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKAogICAgdmFsdWVzID0gYyhGZW1hbGUgPSAiI0JBMjdGRiIsCiAgICBNYWxlID0gIiMxRUMzRkYiKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgZmFjZXRfd3JhcCh2YXJzKENhdGVnb3J5KSkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBWYWx1ZSwgeSA9IFZhbHVlKSwgCiAgICAgICAgICAgIHZqdXN0ID0gMiwgCiAgICAgICAgICAgIGhqdXN0ID0gMC41LCAKICAgICAgICAgICAgc2l6ZSA9IDQpICsKICB4bGFiKCJHU0UgSUQiKSArCiAgeWxhYigiUGVyY2VudGFnZSIpICsKICBsYWJzKHRpdGxlID0gIlNleCIsCiAgICAgICBmaWxsID0gIlNleCIpCgpnZ3NhdmUoU2V4LCBmaWxlID0gIkRlbW9ncmFwaGljc19TZXhfMS5wbmciLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2KQpnZ3NhdmUoU2V4LCBmaWxlID0gIkRlbW9ncmFwaGljc19TZXhfMi5wbmciLCB3aWR0aCA9IDYsIGhlaWdodCA9IDEwKQoKCgpBZ2UgPSBEZW1vZ3JhcGhpY3MgJT4lCiBmaWx0ZXIoIShDYXRlZ29yeSAlaW4lICJTZXgiKSkgJT4lCiBnZ3Bsb3QoKSArCiAgYWVzKHggPSBTdHVkeSwgeSA9IFZhbHVlLCBmaWxsID0gU3ViKSArCiAgZ2VvbV9jb2woKSArCiAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKE1lYW4gPSAiIzFFQzNGRiIpKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBmYWNldF93cmFwKHZhcnMoQ2F0ZWdvcnkpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IFZhbHVlLCB5ID0gVmFsdWUpLCAKICAgICAgICAgICAgdmp1c3QgPSAyLCAKICAgICAgICAgICAgaGp1c3QgPSAwLjUsIAogICAgICAgICAgICBzaXplID0gNCkgKwogIHhsYWIoIkdTRSBJRCIpICsKICB5bGFiKCJBZ2UiKSArCiAgbGFicyhmaWxsID0gIkFnZSIpCgpnZ3NhdmUoQWdlLCBmaWxlID0gIkRlbW9ncmFwaGljc19BZ2VfMS5wbmciLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2KQpnZ3NhdmUoQWdlLCBmaWxlID0gIkRlbW9ncmFwaGljc19BZ2VfMi5wbmciLCB3aWR0aCA9IDYsIGhlaWdodCA9IDEwKQoKYGBgCgoKYGBge3J9CmFubl92YWNjaW5lcyA9IGFubl92YWNjaW5lc18yOV8xMV8yMyAlPiUgCiAgY2xlYW5fbmFtZXMoKSAlPiUgCiAgbXV0YXRlKGNvbmRpdGlvbiA9IGZhY3Rvcihjb25kaXRpb24sIGxldmVscyA9IHJldihjb25kaXRpb24pKSkKCnBsb3QgPSBhbm5fdmFjY2luZXMgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeCA9IGNvbmRpdGlvbiwgCiAgICAgIHkgPSBwYXJ0aWNpcGFudHMsIAogICAgICBmaWxsID0gZ3NlX2lkKSArCiAgZ2VvbV9jb2woKSArCiAgbGFicyh0aXRsZSA9ICJQYXJ0aWNpcGFudHMgYnkgY29uZGl0aW9uIikgKwogIGNvb3JkX2ZsaXAoKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB5bGltKDAsIDcwKSArCiAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKCJHU0UxOTk3NTAiID0gIiM4MGZmZGIiLAogICAgICAgICAgICAgICAiR1NFMjAxNTMzIiA9ICIjNWU2MGNlIiwgCiAgICAgICAgICAgICAgICJHU0UyMDE1MzAiID0gIiM3NDAwYjgiLAogICAgICAgICAgICAgICAiR1NFMjA2MDIzIiA9ICIjNDM2MWVlIiwKICAgICAgICAgICAgICAgIkdTRTE4OTAzOSIgPSAiIzQ4YmZlMyIpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhcnRpY2lwYW50cywgeSA9IHBhcnRpY2lwYW50cyksIAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC45KSwgCiAgICAgICAgICAgIHZqdXN0ID0gMC41LCAKICAgICAgICAgICAgaGp1c3QgPSAtMC4yLCAKICAgICAgICAgICAgc2l6ZSA9IDMpCgpnZ3NhdmUocGxvdCwgZmlsZSA9ICJTYW1wbGVzX3Blcl9jb25kaXRpb25fYnlfR1NFLnBuZyIsIHdpZHRoID0gNiwgaGVpZ2h0ID0gMTApCmdnc2F2ZShwbG90LCBmaWxlID0gIlNhbXBsZXNfcGVyX2NvbmRpdGlvbl9ieV9HU0VfMi5wbmciLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2KQoKCmBgYAoKCgpDb21iaW5hciB0YWJlbGEgZGUgZ2VuZXMgc2VxdWVuY2lhZG9zIChyYXcpCgpgYGB7cn0KI1RBQkVMQSBERSBHRU5FUyBTRVFVRU5DSUFET1MKCmdzZTIwMTUzMF9nZW5lcyA9IGdzZTIwMTUzMF9jb3VudHNfcmVhZHkgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCJnZW5lcyIpICU+JSAKICBzZWxlY3QoZ2VuZXMpICU+JSAKICBtdXRhdGUoc3R1ZHkgPSAiR1NFMjAxNTMwIikKCmdzZTE5OTc1MF9nZW5lcyA9IGdzZTE5OTc1MF9jb3VudHNfcmVhZHkgJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByb3duYW1lc190b19jb2x1bW4oImdlbmVzIikgJT4lIAogIHNlbGVjdChnZW5lcykgJT4lIAogIG11dGF0ZShzdHVkeSA9ICJHU0UxOTk3NTAiKQoKZ3NlMTg5MDM5X2dlbmVzID0gZ3NlMTg5MDM5X2NvdW50c19yZWFkeSAlPiUKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigiZ2VuZXMiKSAlPiUgCiAgc2VsZWN0KGdlbmVzKSAlPiUgCiAgbXV0YXRlKHN0dWR5ID0gIkdTRTE4OTAzOSIpCgpnc2UyMDE1MzNfZ2VuZXMgPSBnc2UyMDE1MzNfY291bnRzX3JlYWR5ICU+JQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCJnZW5lcyIpICU+JSAKICBzZWxlY3QoZ2VuZXMpICU+JSAKICBtdXRhdGUoc3R1ZHkgPSAiR1NFMjAxNTMzIikKCmdzZTIwNjAyM19nZW5lcyA9IGdzZTIwNjAyM19jb3VudHNfbG9uZ19hbm5vdGF0ZWRfMTRfMTFfMjMgJT4lIAogIHNlbGVjdChnZW5lcykgJT4lIAogIGRpc3RpbmN0KCkgJT4lIAogIG11dGF0ZShzdHVkeSA9ICJHU0UyMDYwMjMiKQoKCmdlbmVzX3Jhd19jb21iaW5lZCA9IGJpbmRfcm93cyhnc2UyMDYwMjNfZ2VuZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UyMDE1MzNfZ2VuZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UxODkwMzlfZ2VuZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UxOTk3NTBfZ2VuZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc2UyMDE1MzBfZ2VuZXMpCgoKd3JpdGUuY3N2KGdlbmVzX3Jhd19jb21iaW5lZCwgZmlsZSA9ICJnZW5lc19yYXdfY29tYmluZWQuY3N2IikKCmBgYAoKCiMgNS4gVmlzdWFsaXphw6fDo28gZGUgZGFkb3MKCiMjIERFR3MgcGxvdAoKYGBge3J9Cgphbm5fdmFjY2luZXMgPSBhbm5fdmFjY2luZXNfMjdfMTFfMjMgJT4lIGNsZWFuX25hbWVzKCkKCmFsbF9kZWdzID0gYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWQgJT4lIAogIGdyb3VwX2J5KGNvbmRpdGlvbiwgZGlyZWN0aW9uKSAlPiUgCiAgc3VtbWFyaXNlKERFR3MgPSBuKCkpICU+JSAKICBtZXJnZShhbm5fdmFjY2luZXMsIGJ5PSJjb25kaXRpb24iLCBhbGwueSA9IEYpCgphbGxfZGVnc193aWRlID0gYWxsX2RlZ3MgJT4lIAogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAiZGlyZWN0aW9uIiwgdmFsdWVzX2Zyb20gPSAiREVHcyIpICU+JSAKICBtdXRhdGUoVE9UQUwgPSBzdW0oRE9XTiArIE5FVVRSQUwgKyBVUCkpICU+JSAKICBtZXJnZShhbm5fdmFjY2luZXMsIGJ5PSJjb25kaXRpb24iLCBhbGwueSA9IEYpCgp3cml0ZS5jc3YoYWxsX2RlZ3Nfd2lkZSwgZmlsZSA9ICJhbGxfZGVnc193aWRlLmNzdiIpCgoKCiMgUGxvdCAxCmdncGxvdF9kZWdzX2JhcnMgPSBhbGxfZGVncyAlPiUKIGZpbHRlcighKGRpcmVjdGlvbiAlaW4lICJORVVUUkFMIikpICU+JQogZ2dwbG90KCkgKwogIGFlcyh4ID0gcmVvcmRlcihjb25kaXRpb24sIGRheSksIGZpbGwgPSBkaXJlY3Rpb24sIHdlaWdodCA9IERFR3MpICsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsKICBzY2FsZV9maWxsX21hbnVhbCgKICAgIHZhbHVlcyA9IGMoRE9XTiA9ICIjMEUyNTJEIiwKICAgIE5FVVRSQUwgPSAiIzAwQzE5RiIsCiAgICBVUCA9ICIjMzM5OUZGIikpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGZhY2V0X3dyYXAodmFycyh2YWNfaW5mZWMpLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAyKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IERFR3MsIHkgPSBERUdzKSwgCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCAKICAgICAgICAgICAgdmp1c3QgPSAtMSwgCiAgICAgICAgICAgIGhqdXN0ID0gMC41LCAKICAgICAgICAgICAgc2l6ZSA9IDIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDEsIGhqdXN0PTEsIHNpemUgPSA3KSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IDIpKSArCiAgZ2d0aXRsZSgiREVHcyAtIGFsbCBzdHVkaWVzLCBwPDAuMDUiKQoKZ2dzYXZlKGdncGxvdF9kZWdzX2JhcnMsIGZpbGUgPSAiREVHc191cF9kb3duX2JhcnBsb3RfcHZhbHVlMDVfMS5wbmciLCAgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNikgCgoKZXNxdWlzc2VyKGFsbF9kZWdzKQoKI1Bsb3QgMgpnZ3Bsb3RfZGVnc19iYXJzXzIgPSBhbGxfZGVncyAlPiUKIGZpbHRlcighKGRpcmVjdGlvbiAlaW4lICJORVVUUkFMIikpICU+JQogZ2dwbG90KGFlcyh4ID0gY29uZGl0aW9uLCBmaWxsID0gZGlyZWN0aW9uLCB3ZWlnaHQgPSBERUdzKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKAogICAgdmFsdWVzID0gYyhET1dOID0gIiMwRTI1MkQiLAogICAgTkVVVFJBTCA9ICIjMDBDMTlGIiwKICAgIFVQID0gIiMzMzk5RkYiKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgZmFjZXRfd3JhcCh2YXJzKHZhY2NpbmUpLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAyKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IERFR3MsIHkgPSBERUdzKSwgCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCAKICAgICAgICAgICAgdmp1c3QgPSAtMSwgCiAgICAgICAgICAgIGhqdXN0ID0gMC41LCAKICAgICAgICAgICAgc2l6ZSA9IDIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDEsIGhqdXN0PTEsIHNpemUgPSA3KSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IDIpKSArCiAgZ2d0aXRsZSgiREVHcyAtIGFsbCBzdHVkaWVzLCBwPDAuMDUiKQoKZ2dzYXZlKGdncGxvdF9kZWdzX2JhcnNfMiwgZmlsZSA9ICJERUdzX3VwX2Rvd25fYmFycGxvdF9wdmFsdWUwNV8yLnBuZyIsICB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2KSAKCgoKI1Bsb3QgMwpnZ3Bsb3RfZGVnc19iYXJzXzMgPSBhbGxfZGVncyAlPiUKIGZpbHRlcighKGRpcmVjdGlvbiAlaW4lICJORVVUUkFMIikpICU+JQogZ2dwbG90KCkgKwogIGFlcyh4ID0gY29uZGl0aW9uLCBmaWxsID0gZGlyZWN0aW9uLCB3ZWlnaHQgPSBERUdzKSArCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKERPV04gPSAiIzBFMjUyRCIsCiAgICBORVVUUkFMID0gIiMwMEMxOUYiLAogICAgVVAgPSAiIzMzOTlGRiIpKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBmYWNldF93cmFwKHZhcnModmFjY2luZSksIHNjYWxlcyA9ICJmcmVlIiwgbnJvdyA9IDcpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gREVHcywgeSA9IERFR3MpLCAKICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSksIAogICAgICAgICAgICB2anVzdCA9IC0xLCAKICAgICAgICAgICAgaGp1c3QgPSAwLjUsIAogICAgICAgICAgICBzaXplID0gMikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHZqdXN0ID0gMSwgaGp1c3Q9MSwgc2l6ZSA9IDcpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMikpICsKICBnZ3RpdGxlKCJERUdzIC0gYWxsIHN0dWRpZXMsIHA8MC4wNSIpCgpnZ3NhdmUoZ2dwbG90X2RlZ3NfYmFyc18zLCBmaWxlID0gIkRFR3NfdXBfZG93bl9iYXJwbG90X3B2YWx1ZTA1XzMucG5nIiwgIHdpZHRoID0gNSwgaGVpZ2h0ID0gMjApCgoKI1Bsb3QgNApnZ3Bsb3RfZGVnc19iYXJzXzQgPSBhbGxfZGVncyAlPiUKIGZpbHRlcihkaXJlY3Rpb24gIT0iTkVVVFJBTCIsCiAgICAgICAgdmFjX2luZmVjICE9ICJ2YWNjaW5lIikgJT4lCiBnZ3Bsb3QoKSArCiAgYWVzKHggPSBjb25kaXRpb24sIGZpbGwgPSBkaXJlY3Rpb24sIHdlaWdodCA9IERFR3MpICsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsKICBzY2FsZV9maWxsX21hbnVhbCgKICAgIHZhbHVlcyA9IGMoRE9XTiA9ICIjMEUyNTJEIiwKICAgIE5FVVRSQUwgPSAiIzAwQzE5RiIsCiAgICBVUCA9ICIjMzM5OUZGIikpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGZhY2V0X2dyaWQodmFycyhwcmlvcl9pbmZlY3Rpb24pLCB2YXJzKHByZXZpb3VzX3ZhY2NpbmF0aW9uKSwgc2NhbGVzID0gImZyZWUiKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IERFR3MsIHkgPSBERUdzKSwgCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCAKICAgICAgICAgICAgdmp1c3QgPSAtMSwgCiAgICAgICAgICAgIGhqdXN0ID0gMC41LCAKICAgICAgICAgICAgc2l6ZSA9IDIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDEsIGhqdXN0PTEsIHNpemUgPSA3KSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IDIpKSArCiAgZ2d0aXRsZSgiREVHcyAtIGFsbCBzdHVkaWVzLCBwPDAuMDUiKQoKZ2dzYXZlKGdncGxvdF9kZWdzX2JhcnNfNCwgZmlsZSA9ICJERUdzX3VwX2Rvd25fYmFycGxvdF9wdmFsdWUwNV80LnBuZyIsICB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2KQoKYGBgCgojIyA1LjEuIFZvbGNhbm9wbG90CgpPcyB2b2xjYW5vcGxvdHMgZGFzIGR1YXMgdmFjaW5hcyBzw6NvIG9zIG1lc21vcywgbWFzIGVzcGVsaGFkb3MuIElzc28gc2lnbmlmaWNhIHF1ZSBkZWZpbmlyIG8gbml2ZWwgZGUgcmVmZXJlbmNpYSBubyBmYXRvciBkZSB2YWNpbmFzIMOpIGltcG9ydGFudGUgcGFyYSBkZXRlcm1pbmFyIGFzIERFR3MgdXAgZSBkb3duLiBcIyMjIyBBU1RSQVpFTkVDQQoKKkFzdHJhemVuZWNhKiAKCmBgYHtyfQoKI0FsbAp2b2xjYW5vX3JlcyA8LSBFbmhhbmNlZFZvbGNhbm8ocmVzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiID0gcm93bmFtZXMocmVzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICdsb2cyRm9sZENoYW5nZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAncHZhbHVlJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9J0RpZmZlcmVudGlhbCBleHByZXNzaW9uIG9mIGdlbmVzIC0gQWxsIHRpbWVwb2ludHMgLSBDaEFkT3gxJykKIyBTYXZlIHRoZSBwbG90IGFzIGEgUE5HIGZpbGUKcG5nKCJnc2UxOTk3NTBfdm9sY2Fub3Bsb3RfREVHc19hbGxmYWN0b3Jlc19BWi5wbmciLCB3aWR0aCA9IDgwMCwgaGVpZ2h0ID0gNjAwKQpwcmludCh2b2xjYW5vX3Jlc19jaGFkKQpkZXYub2ZmKCkKCiNUMS1UMAp2b2xjYW5vX3Jlc19jaGFkXzFfMCA8LSBFbmhhbmNlZFZvbGNhbm8ocmVzXzFfMF9jaGFkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiID0gcm93bmFtZXMocmVzXzFfMF9jaGFkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICdsb2cyRm9sZENoYW5nZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAncHZhbHVlJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9J0RpZmZlcmVudGlhbCBleHByZXNzaW9uIG9mIGdlbmVzIC0gRDEgdnMuIEQwIC0gQ2hBZE94MScpCiMgU2F2ZSB0aGUgcGxvdCBhcyBhIFBORyBmaWxlCnBuZygiZ3NlMTk5NzUwX3ZvbGNhbm9wbG90X0RFR3NfRDAtRDFfQVoucG5nIiwgd2lkdGggPSA4MDAsIGhlaWdodCA9IDYwMCkKcHJpbnQodm9sY2Fub19yZXNfY2hhZF8xXzApCmRldi5vZmYoKQoKI1QyLVQwCnZvbGNhbm9fcmVzX2NoYWRfMl8wIDwtIEVuaGFuY2VkVm9sY2FubyhyZXNfdGltZTBfdGltZTJfY2hhZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYiA9IHJvd25hbWVzKHJlc190aW1lMF90aW1lMl9jaGFkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICdsb2cyRm9sZENoYW5nZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAncHZhbHVlJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9J0RpZmZlcmVudGlhbCBleHByZXNzaW9uIG9mIGdlbmVzIC0gRDIgdnMuIEQwIC0gQ2hBZE94MScpCiMgU2F2ZSB0aGUgcGxvdCBhcyBhIFBORyBmaWxlCnBuZygiZ3NlMTk5NzUwX3ZvbGNhbm9wbG90X0RFR3NfRDAtRDJfQVoucG5nIiwgd2lkdGggPSA4MDAsIGhlaWdodCA9IDYwMCkKcHJpbnQodm9sY2Fub19yZXNfY2hhZF8yXzApCmRldi5vZmYoKQoKI1Bsb3RhciBtYWlzIGRlIHVtIGdyw6FmaWNvCnBsb3RfZ3JpZCh2b2xjYW5vX3Jlc19jaGFkLCB2b2xjYW5vX3Jlc19jaGFkXzFfMCwgdm9sY2Fub19yZXNfY2hhZF8yXzAsIG5jb2wgPSAzKSAKCmBgYAoKIyMgNS4yLiBIZWF0bWFwCgpgYGB7cn0KIyB0ZXN0ZSBoZWF0bWFwCmhlYWQocmVzKQoKI09idGVyIERFR3MgZG8gZXN0dWRvCmhlYXRfdGVzdCA9IHJlcyAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByb3duYW1lc190b19jb2x1bW4odmFyPSJnZW5lcyIpCgojT2J0ZXIgY291bnRzIGRvcyBERUdzCmhlYXRfY291bnQgPSBjb3VudERhdGEgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAiZ2VuZXMiKQoKI1VuaXIgdGFiZWxhcwojIyNBIHRhYmVsYSBhZ29yYSBwb3NzdWkgb3MgdmFsb3JlcyBkZSBjb3VudHMgZSBvdXRyYXMgZXN0YXTDrXN0aWNhcyBkbyBvYmpldG8gZGVzZXEyIHBhcmVhZGFzIHBlbG9zIERFR3MuCm1lcmdlZF9oZWF0ID0gaGVhdF90ZXN0ICU+JSAKICBtZXJnZShoZWF0X2NvdW50LCBieSA9ICdnZW5lcycpICU+JSAKICBhcnJhbmdlKHBhZGopCgojQ29yZXMKdHBfY29scyA9IGMoIlYwIiA9ICJzdGVlbGJsdWUyIiwgIlYxIiA9ICJnb2xkZW5yb2QiLCJWMkEiPSJmaXJlYnJpY2szIiwiVjNBIj0iZ3JleTQ0IikKdl9jb2xzID0gYygiQ2hBZE94MSIgPSAidmlvbGV0cmVkMiIsICJCTlQxNjJiMiIgPSAiZGVlcHNreWJsdWUyIiwibVJOQS0xMjczIiA9ICJnb2xkZW5yb2QiKQoKIyBUcmFuc2Zvcm1hciBhcyBjb3VudHMgZG9zIERFR3MgZW0gbWF0cml6IGUgbm9ybWFsaXphciAKZGF0YTJwbG90IDwtIGFzLm1hdHJpeChtZXJnZWRfaGVhdFssIDg6MjY3XSkKenp6IDwtIHNjYWxlKHQoZGF0YTJwbG90KSkgJT4lCiAgcG1pbigtMykgJT4lCiAgcG1heCgzKSkKCiNUcmFuc2Zvcm1hciBlbSBkYXRhZnJhbWUKdGVzdCA8LSB6enogJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JQogIG11dGF0ZShnZW5lcyA9IG1lcmdlZF9oZWF0JGdlbmVzKSAlPiUKICB0aWR5cjo6Z2F0aGVyKCJzYW1wbGVzIiwgImV4cHJlc3Npb24iLCAtZ2VuZXMpCnRhaWwodGVzdCkKCnp6el9maWx0ZXJlZCA9IHRlc3QgJT4lIAogIHN1YnNldChleHByZXNzaW9uID4gMiAmIHNhbXBsZXMgPT0gJ0NPVklSU180MV9WMCcpCmRpbSh6enpfZmlsdGVyZWQpCmhlYWQoenp6X2ZpbHRlcmVkKQoKI0hlYXRtYXAgYW5ub3RhdGlvbgpoYSA9IEhlYXRtYXBBbm5vdGF0aW9uKGRmID0gY29sRGF0YVssYygidGltZXBvaW50IiwiZmlyc3Rfc2Vjb25kX2Rvc2VmIildLAogICAgICAgICAgICAgICAgICAgICAgIGNvbCA9IGxpc3QoVGltZXBvaW50ID0gdHBfY29scywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpcnN0U2Vjb25kRG9zZWYgPSB2X2NvbHMpKQoKSGVhdG1hcCh6enosIAogICAgICAgIHNob3dfcm93X25hbWVzID0gRkFMU0UsCiAgICAgICAgc2hvd19jb2x1bW5fbmFtZXMgPSBGQUxTRSwKICAgICAgICBjbHVzdGVyX3Jvd3M9VFJVRSwKICAgICAgICBjbHVzdGVyX2NvbHVtbnMgPSBUUlVFLAogICAgICAgIHRvcF9hbm5vdGF0aW9uID0gaGEsCiAgICAgICAgY29sPWMoImRhcmtncmVlbiIsImF6dXJlMiIsImRhcmtvcmNoaWQ0IiksCiAgICAgICAgY29sdW1uX3NwbGl0PWNvbERhdGEkVGltZXBvaW50LAogICAgICAgIGNvbHVtbl90aXRsZT0iSGVhdHBsb3QiKQoKYGBgCgojIyA1LjMuIERpYWdyYW1hIGRlIFZlbm4gY29tIEhlYXRtYXAKCipUYWJlbGEgZGUgb3ZlcmxhcHMgZGUgREVHcyBjb20gdGVzdGUgZXhhdG8gZGUgZmlzaGVyKgoKRGV0ZXJtaW5hciBhIHByb3BvcsOnw6NvIGRlIERFR3MgY29tcGFydGlsaGFkYXMgZW50cmUgY29uZGnDp8O1ZXMgZGlmZXJlbnRlcyBlIHN1YSBzaWduaWZpY8OibmNpYS4gTyBjw7NkaWdvIGFiYWl4byBkZXZlIHRlciBjb21vIGlucHV0IHVtYSB0YWJlbGEgbG9uZ2EgY2hhbWFkYSAiZGVnc19hbGwiIChjb2x1bmEgMTogY29uZGljb2VzL3ZhY2luYXMsIGNvbHVuYSAyOiBERUdzKS4gTyBvdXRwdXQgc2Vyw6EgdW1hIHRhYmVsYSBsb25nYSBjb20gYXMgY29sdW5hcyBWYWNpbmEgMSwgVmFjaW5hIDIsIHNoYXJlZCBkZWdzLCBub3Qgc2hhcmVkIHZhY2luYSAxLCBub3Qgc2hhcmVkIHZhY2luYSAyLCBsaXN0YSBjb20gbm9tZXMgZGFzIGRlZ3MsIHZhbG9yIHAgZGUgZmlzaGVyICh0ZXN0ZSBleGF0byBkZSBmaXNoZXIpLgoKCgoKYGBge3J9CgojQ29udmVydGVyIHRhYmVsYSBkZSBERUdzIFVwIGFuZCBEb3duIGVtIHRhYmVsYSBsb25nYQpkZWdzX2FsbF91cGRvd24gPSBkZWdzX3VwZG93bl9wXzA1X3ZhY19pbmZlY3RlZCAlPiUgCiAgZmlsdGVyKGRpcmVjdGlvbiAhPSAiTkVVVFJBTCIpICU+JSAKICBtdXRhdGVfYWxsKH4gcmVwbGFjZSguLCBpcy5uYSguKSwgIk5BIikpCgojU2FsdmFyCndyaXRlLmNzdihkZWdzX2FsbF91cGRvd24sIGZpbGU9ICJkZWdzX3VwZG93bl9wPDA1X3ZhY19pbmZlY3RlZC5jc3YiKQoKIyBUYWJlbGEgZGUgZGFkb3MKCiNVcCB2cyBVcApkZWdzX3Zlbm5fdXAgPSBkZWdzX2FsbF91cGRvd24gJT4lIAogIGZpbHRlcihkaXJlY3Rpb24gPT0gIlVQIikgJT4lCiAgbXV0YXRlKGNvbXBhcmlzb24gPSAiVVAtVVAiKSAlPiUgCiAgc2VsZWN0KGNvbmRpdGlvbiwgZ2VuZXMpCgojRG93biB2cyBEb3duCmRlZ3NfdmVubl9kb3duID0gZGVnc19hbGxfdXBkb3duICU+JSAKICBmaWx0ZXIoZGlyZWN0aW9uID09ICJET1dOIikgJT4lCiAgbXV0YXRlKGNvbXBhcmlzb24gPSAiRE9XTi1ET1dOIikgJT4lIAogIHNlbGVjdChjb25kaXRpb24sIGdlbmVzKQoKCiMgRE9XTi1VUCBBTEwKZGVnc192ZW5uX3VwZG93biA9IGRlZ3NfYWxsX3VwZG93biAlPiUgCiAgZmlsdGVyKGRpcmVjdGlvbiAlaW4lIGMoIlVQIiwgIkRPV04iKSkgJT4lCiAgbXV0YXRlKGNvbXBhcmlzb24gPSAiVVBfQU5EX0RPV04iKSAlPiUgCiAgc2VsZWN0KGNvbmRpdGlvbiwgZ2VuZXMpCgojVXAgdnMgRG93bgpkZWdzX3Zlbm5fdXBfdnNfZG93biA9IGRlZ3NfYWxsX3VwZG93biAlPiUgCiAgbXV0YXRlKGNvbXBhcmlzb24gPSAiVVBfdnNfRE9XTiIpICU+JSAKICBzZWxlY3QoY29uZGl0aW9uLCBnZW5lcykKCmBgYAoKCmBgYHtyfQojSW5wdXQKZGF0YSA9IGRlZ3NfdmVubl9kb3duCmZpbGVuYW1lID0gImRlZ3NfdmVubl9kb3duIgoKIyBGdW7Dp8OjbyBwYXJhIGNhbGN1bGFyIGEgc29icmVwb3Npw6fDo28gZW50cmUgcGFyZXMgZGUgdmFjaW5hcyBlIGEgcG9yY2VudGFnZW0gZGUgZ2VuZXMgY29tcGFydGlsaGFkb3MKb3ZlcmxhcF9nZW5lcyA8LSBmdW5jdGlvbihjb25kMSwgY29uZDIsIGRhdGEpIHsKICBnZW5lc19jb25kMSA8LSBkYXRhJGdlbmVzW2RhdGEkY29uZGl0aW9uID09IGNvbmQxXSAjVHJvY2FyIGNvbHVuYQogIGdlbmVzX2NvbmQyIDwtIGRhdGEkZ2VuZXNbZGF0YSRjb25kaXRpb24gPT0gY29uZDJdICNUcm9jYXIgY29sdW5hCiAgZ2VuZXNfc2hhcmVkIDwtIGludGVyc2VjdChnZW5lc19jb25kMSwgZ2VuZXNfY29uZDIpCiAgZ2VuZXNfbm90c2hhcmVkX2NvbmQxIDwtIHNldGRpZmYoZ2VuZXNfY29uZDEsIGdlbmVzX2NvbmQyKQogIGdlbmVzX25vdHNoYXJlZF9jb25kMiA8LSBzZXRkaWZmKGdlbmVzX2NvbmQyLCBnZW5lc19jb25kMSkKICAKICB0b3RhbF9nZW5lc19jb25kMSA8LSBsZW5ndGgoZ2VuZXNfY29uZDEpCiAgdG90YWxfZ2VuZXNfY29uZDIgPC0gbGVuZ3RoKGdlbmVzX2NvbmQyKQogIAogIHBlcmNlbnRhZ2Vfc2hhcmVkX2NvbmQxIDwtIGxlbmd0aChnZW5lc19zaGFyZWQpIC8gdG90YWxfZ2VuZXNfY29uZDEgKiAxMDAKICBwZXJjZW50YWdlX3NoYXJlZF9jb25kMiA8LSBsZW5ndGgoZ2VuZXNfc2hhcmVkKSAvIHRvdGFsX2dlbmVzX2NvbmQyICogMTAwCiAgCiAgc2hhcmVkX2dlbmVzIDwtIGRhdGEuZnJhbWUoCiAgICBDb25kMSA9IGNvbmQxLAogICAgQ29uZDIgPSBjb25kMiwKICAgIFNoYXJlZCA9IGxlbmd0aChnZW5lc19zaGFyZWQpLAogICAgTm90U2hhcmVkX2NvbmQxID0gbGVuZ3RoKGdlbmVzX25vdHNoYXJlZF9jb25kMSksCiAgICBOb3RTaGFyZWRfY29uZDIgPSBsZW5ndGgoZ2VuZXNfbm90c2hhcmVkX2NvbmQyKSwKICAgIFRvdGFsX0dlbmVzX0NvbmQxID0gdG90YWxfZ2VuZXNfY29uZDEsCiAgICBUb3RhbF9HZW5lc19Db25kMiA9IHRvdGFsX2dlbmVzX2NvbmQyLAogICAgR2VuZXNfTmFtZXMgPSBwYXN0ZShnZW5lc19zaGFyZWQsIGNvbGxhcHNlID0gIiwgIiksCiAgICBQZXJjZW50YWdlX1NoYXJlZF9Db25kMSA9IHBlcmNlbnRhZ2Vfc2hhcmVkX2NvbmQxLAogICAgUGVyY2VudGFnZV9TaGFyZWRfQ29uZDIgPSBwZXJjZW50YWdlX3NoYXJlZF9jb25kMgogICkKICAKICByZXR1cm4oc2hhcmVkX2dlbmVzKQp9CiMgT2J0ZW5oYSB1bWEgbGlzdGEgZGUgdG9kYXMgYXMgdmFjaW5hcyDDum5pY2FzCnVuaXF1ZV9jb25kIDwtIHVuaXF1ZShkYXRhJGNvbmRpdGlvbikgICN0cm9jYXIgInN0dWR5IiBwZWxvIG5vbWUgZGEgY29sdW5hIGRlIGludGVyZXNzZQoKIyBJbmljaWFsaXplIHVtIGRhdGFmcmFtZSBwYXJhIGFybWF6ZW5hciBvcyByZXN1bHRhZG9zCnNoYXJlZF9nZW5lc19kZiA8LSBkYXRhLmZyYW1lKCkKCiMgQ2FsY3VsYXIgYSBzb2JyZXBvc2nDp8OjbyBlIHBvcmNlbnRhZ2VtIHBhcmEgY2FkYSBwYXIgZGUgdmFjaW5hcwpmb3IgKGkgaW4gMToobGVuZ3RoKHVuaXF1ZV9jb25kKSAtIDEpKSB7CiAgZm9yIChqIGluIChpICsgMSk6bGVuZ3RoKHVuaXF1ZV9jb25kKSkgewogICAgcmVzdWx0YWRvX3RlbXAgPC0gb3ZlcmxhcF9nZW5lcyh1bmlxdWVfY29uZFtpXSwgdW5pcXVlX2NvbmRbal0sIGRhdGEpCiAgICBzaGFyZWRfZ2VuZXNfZGYgPC0gYmluZF9yb3dzKHNoYXJlZF9nZW5lc19kZiwgcmVzdWx0YWRvX3RlbXApCiAgfQp9CgojIEZ1bsOnw6NvIHBhcmEgcmVhbGl6YXIgbyB0ZXN0ZSBleGF0byBkZSBGaXNoZXIKZmlzaGVyX2V4YWN0X3Rlc3QgPC0gZnVuY3Rpb24oc2hhcmVkLCBub3RzaGFyZWQxLCBub3RzaGFyZWQyKSB7CiAgY29udF90YWJsZSA8LSBtYXRyaXgoYyhzaGFyZWQsIG5vdHNoYXJlZDEsIG5vdHNoYXJlZDIsIDApLCBucm93ID0gMikKICByZXN1bHRzX2Zpc2hlciA8LSBmaXNoZXIudGVzdChjb250X3RhYmxlKQogIHJldHVybihyZXN1bHRzX2Zpc2hlciRwLnZhbHVlKQp9CgojIEFwbGljYXIgYSBmdW7Dp8OjbyBhIGNhZGEgbGluaGEgZGEgdGFiZWxhIGRlIHJlc3VsdGFkb3MKc2hhcmVkX2dlbmVzX2RmJHB2YWx1ZSA8LSBtYXBwbHkoZmlzaGVyX2V4YWN0X3Rlc3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFyZWRfZ2VuZXNfZGYkU2hhcmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcmVkX2dlbmVzX2RmJE5vdFNoYXJlZF9jb25kMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXJlZF9nZW5lc19kZiROb3RTaGFyZWRfY29uZDIpCgoKIyBDYWxjdWxhciBxdmFsdWUgKEJIKSBlIC1sb2coRkRSKQpzaGFyZWRfZ2VuZXNfZGYgPC0gc2hhcmVkX2dlbmVzX2RmICU+JQogIG11dGF0ZShxdmFsdWUgPSBxdmFsdWUocHZhbHVlKSRxdmFsdWVzKQoKIyBDYWxjdWxhciAtbG9nKHEpCnNoYXJlZF9nZW5lc19kZiRgbG9nX3FgPSAtbG9nKHNoYXJlZF9nZW5lc19kZiRxdmFsdWUsIDEwKQoKCiNEdXBsaWNhciBlIHRyb2NhciBjb2x1bmFzIChWYWNpbmEgMSBlIFZhY2luYSAyKQpzaGFyZWRfZ2VuZXNfZGYyID0gc2hhcmVkX2dlbmVzX2RmCnNoYXJlZF9nZW5lc19kZjJbLCBjKCJDb25kMSIsICJDb25kMiIpXSA8LSBzaGFyZWRfZ2VuZXNfZGYyWywgYygiQ29uZDIiLCAiQ29uZDEiKV0KCiNVbmlyIGRhdGFzZXRzIGNvbSBvcyBkYWRvcyBlc3BlbGhhZG9zCnNoYXJlZF9nZW5lc19kZl9taXJyb3IgPSByYmluZChzaGFyZWRfZ2VuZXNfZGYsIHNoYXJlZF9nZW5lc19kZjIpCgojQ29udmVydGVyIE5BLCBOYU5lIGluZiBlbSAwCnNoYXJlZF9nZW5lc19kZl9taXJyb3JbaXMubmEoc2hhcmVkX2dlbmVzX2RmX21pcnJvcildIDwtIDAKc2hhcmVkX2dlbmVzX2RmX21pcnJvcjwtIHJlcGxhY2Uoc2hhcmVkX2dlbmVzX2RmX21pcnJvciwgc2hhcmVkX2dlbmVzX2RmX21pcnJvciA9PSAiSW5mIiwgMCkKCiNBcnJlZG9uZGFyIHBvcmNlbnRhZ2VucwpzaGFyZWRfZ2VuZXNfZGZfbWlycm9yID0gc2hhcmVkX2dlbmVzX2RmX21pcnJvciAlPiUKICBtdXRhdGUoUGVyY2VudGFnZV9TaGFyZWRfQ29uZDEgPSByb3VuZChQZXJjZW50YWdlX1NoYXJlZF9Db25kMSwgMiksCiAgICAgICAgIFBlcmNlbnRhZ2VfU2hhcmVkX0NvbmQyID0gcm91bmQoUGVyY2VudGFnZV9TaGFyZWRfQ29uZDIsIDIpKQoKI1NhbHZhciByZXN1bHRhZG9zCndyaXRlLmNzdihzaGFyZWRfZ2VuZXNfZGZfbWlycm9yLCBmaWxlID0gcGFzdGUwKCJzaGFyZWRfIiwgZmlsZW5hbWUsICJfZmlzaGVyX3B2YWx1ZTEwLmNzdiIpKSAjQWx0ZXJhcgoKI0ZpbHRyYXIKc2hhcmVkX2dlbmVzX2RmX21pcnJvcl9xMTAgPSBzaGFyZWRfZ2VuZXNfZGZfbWlycm9yICU+JSAKICBmaWx0ZXIocXZhbHVlIDwgMC4xMCkKd3JpdGUuY3N2KHNoYXJlZF9nZW5lc19kZl9taXJyb3JfcTEwLCBmaWxlID0gcGFzdGUwKCJzaGFyZWRfIiwgZmlsZW5hbWUsICJfZmlzaGVyX3A8MTBfcXZhbHVlMTAuY3N2IikpCgpgYGAKCgoqcEhlYXRtYXAqCgpgYGB7cn0KI01hdHJpegpzaGFyZWRfaGVhdG1hcCA9IHNoYXJlZF9nZW5lc19kZl9taXJyb3JfcTEwICU+JSAKICBkY2FzdChDb25kMSB+IENvbmQyLCAKICAgICAgICB2YWx1ZS52YXIgPSAiUGVyY2VudGFnZV9TaGFyZWRfQ29uZDEiLCAKICAgICAgICBmdW4uYWdncmVnYXRlID0gbWVhbikgJT4lIAogICNyZXBsYWNlKGlzLm5hKC4pLCAwKSAlPiUgCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJDb25kMSIpICU+JSAKICBhcy5tYXRyaXgoKQoKI0Fub3RhciBjb2x1bmFzCnNoYXJlZF9oZWF0bWFwX2FubiA9IHNoYXJlZF9oZWF0bWFwICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIHJvd25hbWVzX3RvX2NvbHVtbigiY29uZGl0aW9uIikgJT4lIAogIHNlbGVjdChjb25kaXRpb24pCgphbm5fdmFjY2luZXNfcGhlYXRtYXAgPSBkZWdzX2FsbF91cGRvd24gJT4lIAogIHNlbGVjdChjb25kaXRpb24sIHZhY2NpbmU6dmFyaWFudCwgLXR5cGUsIC1nc2VfaWQsIC12YWNfaW5mZWMpICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBtdXRhdGUoZGF5ID0gYXMuZmFjdG9yKGRheSksCiAgICAgICAgIGRvc2UgPSBhcy5mYWN0b3IoZG9zZSksCiAgICAgICAgIGluZmVjdGlvbiA9IGFzLmZhY3RvcihpbmZlY3Rpb24pLAogICAgICAgICB2YXJpYW50ID0gYXMuZmFjdG9yKHZhcmlhbnQpLAogICAgICAgICByZWdpbWVuID0gYXMuZmFjdG9yKHJlZ2ltZW4pLAogICAgICAgICBzZXZlcml0eSA9IGFzLmZhY3RvcihzZXZlcml0eSkpICU+JSAKICBtZXJnZShzaGFyZWRfaGVhdG1hcF9hbm4sIGJ5ID0gImNvbmRpdGlvbiIpICU+JSAjIG1hdGNoIG51bWVybyBkZSBjb2x1bmFzL2xpbmhhcyBkYSBtYXRyaXogCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJjb25kaXRpb24iKQoKCgojUGxvdGFyCnBoZWF0bWFwX3NoYXJlZCA9IHBoZWF0bWFwKHNoYXJlZF9oZWF0bWFwLAogICAgICAgICBtYWluPSBwYXN0ZTAoIlNoYXJlZCAlIiwgZmlsZW5hbWUsICJfcTwwLjEwX3Jvd3NfdnNfY29scyIpLAogICAgICAgICBjb2xvciA9IHJldihoY2wuY29sb3JzKDUwLCAiUmVkcyAzIikpLAogICAgICAgICBicmVha3MgPSBjKHNlcSgwLCAxMCwgbGVuZ3RoLm91dCA9IDApLCAgIyBMb3cgdmFsdWVzCiAgICAgICAgICAgICAgICAgICAgc2VxKDEwLCA1MCwgbGVuZ3RoLm91dCA9IDUwKSwgIyBNaWQgdmFsdWVzCiAgICAgICAgICAgICAgICAgICAgc2VxKDUwLCAxMDAsIGxlbmd0aC5vdXQgPSA1MCkpLCAjIEhpZ2ggdmFsdWVzLCwgCiAgICAgICAgIGNsdXN0ZXJfcm93cyA9IFQsCiAgICAgICAgIGNsdXN0ZXJfY29scyA9IFQsCiAgICAgICAgIGN1dHJlZV9yb3dzID0gNiwKICAgICAgICAgY3V0cmVlX2NvbHMgPSA2LAogICAgICAgICB0cmVlaGVpZ2h0X3JvdyA9IDAsICNhbHR1cmEgZG8gZGVuZHJvZ3JhbWEsIDAgcGFyYSBuw6NvIG1vc3RyYXIKICAgICAgICAgdHJlZWhlaWdodF9jb2wgPSAwLAogICAgICAgICBkaXNwbGF5X251bWJlcnMgPSBULAogICAgICAgICBudW1iZXJfY29sb3IgPSAiYmxhY2siLAogICAgICAgICBmb250c2l6ZV9udW1iZXIgPSA0LAogICAgICAgICBmb250c2l6ZV9yb3cgPSA2LCAKICAgICAgICAgZm9udHNpemVfY29sID0gNiwKICAgICAgICAgbmFfY29sID0gImJsYWNrIiwKICAgICAgICAgc2hvd19jb2xuYW1lcyA9IFQsCiAgICAgICAgIGJvcmRlcl9jb2xvciA9ICJOQSIsCiAgICAgICAgIGFubm90YXRpb25fY29sID0gYW5uX3ZhY2NpbmVzX3BoZWF0bWFwLAogICAgICAgICBhbm5vdGF0aW9uX3JvdyA9IGFubl92YWNjaW5lc19waGVhdG1hcCwKICAgICAgICAgYW5ub3RhdGlvbl9jb2xvcnMgPSBhbm5fY29sb3JzLAogICAgICAgICBhbm5vdGF0aW9uX2xlZ2VuZCA9IEYpCgojU2FsdmFyIGltYWdlbQpwbmcoZmlsZT0gcGFzdGUwKCJzaGFyZWQiLCBmaWxlbmFtZSwgIl9wPDEwX3F2YWx1ZTEwX1BIRUFUTUFQX251bWJlcnMucG5nIiksIAogICAgd2lkdGg9MzAwMCwgCiAgICBoZWlnaHQ9MjAwMCwgCiAgICByZXM9MzE1LCAKICAgIHBvaW50c2l6ZT0xMCkKcHJpbnQocGhlYXRtYXBfc2hhcmVkKQpkZXYub2ZmKCkKYGBgCgoKYGBge3J9CiNQbG90YXIKcGhlYXRtYXBfc2hhcmVkX25vbnVtYmVycyA9IHBoZWF0bWFwKHNoYXJlZF9oZWF0bWFwLAogICAgICAgICBtYWluPSBwYXN0ZTAoIlNoYXJlZCAlIiwgZmlsZW5hbWUsICJfcTwwLjEwX3Jvd3NfdnNfY29scyIpLAogICAgICAgICBjb2xvciA9IHJldihoY2wuY29sb3JzKDUwLCAiUmVkcyAzIikpLAogICAgICAgICBicmVha3MgPSBjKHNlcSgwLCAxMCwgbGVuZ3RoLm91dCA9IDApLCAgIyBMb3cgdmFsdWVzCiAgICAgICAgICAgICAgICAgICAgc2VxKDEwLCA1MCwgbGVuZ3RoLm91dCA9IDUwKSwgIyBNaWQgdmFsdWVzCiAgICAgICAgICAgICAgICAgICAgc2VxKDUwLCAxMDAsIGxlbmd0aC5vdXQgPSA1MCkpLCAjIEhpZ2ggdmFsdWVzLCwgCiAgICAgICAgIGNsdXN0ZXJfcm93cyA9IFQsCiAgICAgICAgIGNsdXN0ZXJfY29scyA9IFQsCiAgICAgICAgIGN1dHJlZV9yb3dzID0gNSwKICAgICAgICAgY3V0cmVlX2NvbHMgPSA1LAogICAgICAgICB0cmVlaGVpZ2h0X3JvdyA9IDAsICNhbHR1cmEgZG8gZGVuZHJvZ3JhbWEsIDAgcGFyYSBuw6NvIG1vc3RyYXIKICAgICAgICAgdHJlZWhlaWdodF9jb2wgPSAwLAogICAgICAgICBkaXNwbGF5X251bWJlcnMgPSBGLAogICAgICAgICBudW1iZXJfY29sb3IgPSAiYmxhY2siLAogICAgICAgICBmb250c2l6ZV9udW1iZXIgPSA0LAogICAgICAgICBmb250c2l6ZV9yb3cgPSA2LCAKICAgICAgICAgZm9udHNpemVfY29sID0gNiwKICAgICAgICAgbmFfY29sID0gImJsYWNrIiwKICAgICAgICAgc2hvd19jb2xuYW1lcyA9IFQsCiAgICAgICAgIGJvcmRlcl9jb2xvciA9ICJOQSIsCiAgICAgICAgIGFubm90YXRpb25fY29sID0gYW5uX3ZhY2NpbmVzX3BoZWF0bWFwLAogICAgICAgICBhbm5vdGF0aW9uX3JvdyA9IGFubl92YWNjaW5lc19waGVhdG1hcCwKICAgICAgICAgYW5ub3RhdGlvbl9jb2xvcnMgPSBhbm5fY29sb3JzLAogICAgICAgICBhbm5vdGF0aW9uX2xlZ2VuZCA9IEYpCgojU2FsdmFyIGltYWdlbQpwbmcoZmlsZT0gcGFzdGUwKCJzaGFyZWQiLCBmaWxlbmFtZSwgIl9wPDEwX3F2YWx1ZTEwX1BIRUFUTUFQX25vbnVtYmVycy5wbmciKSwgCiAgICB3aWR0aD0zMDAwLCAKICAgIGhlaWdodD0yMDAwLCAKICAgIHJlcz0zMTUsIAogICAgcG9pbnRzaXplPTEwKQpwcmludChwaGVhdG1hcF9zaGFyZWRfbm9udW1iZXJzKQpkZXYub2ZmKCkKYGBgCgoKKkNob3JkIGRpYWdyYW0qCgpgYGB7cn0KI0Nob3JkIGRpYWdyYW0KaW5zdGFsbC5wYWNrYWdlcygiY2lyY2xpemUiKQpsaWJyYXJ5KGNpcmNsaXplKQoKIyBzaGFyZWRERUdzX1VQRE9XTl9maXNoZXJfcHZhbHVlMTAKIyBzaGFyZWRERUdzX1VQX2Zpc2hlcl9wXzEwX3B2YWx1ZTEwCiMgc2hhcmVkREVHc19ET1dOX2Zpc2hlcl9wXzEwX3B2YWx1ZTEwCgojSW5wdXQKc2hhcmVkX2dlbmVzX2RmX21pcnJvcl9wMTAgPSBzaGFyZWRERUdzX1VQX2Zpc2hlcl9wXzEwX3B2YWx1ZTEwCgoKI0FsbCBkb3NlcwpjaXJjb3NfYWxsZG9zZXMgPSBzaGFyZWRfZ2VuZXNfZGZfbWlycm9yX3AxMCAlPiUgCiAgc2VsZWN0KENvbmQxLCBDb25kMiwgU2hhcmVkKSAlPiUgCiAgbXV0YXRlKFNoYXJlZCA9IGFzLm51bWVyaWMoU2hhcmVkKSkgJT4lICAKICBtZXJnZShhbm5fdmFjY2luZXMsIGJ5LnggPSAiQ29uZDEiLCBieS55PSJDb25kaXRpb24iLCBhbGwueD1ULCBhbGwueT1GKSAlPiUKICBtZXJnZShhbm5fdmFjY2luZXMsIGJ5LnggPSAiQ29uZDIiLCBieS55PSJDb25kaXRpb24iLCBhbGwueD1ULCBhbGwueT1GKSAlPiUgCiAgc2VsZWN0KENvbmQxLCBDb25kMiwgU2hhcmVkLERvc2UueCwgRG9zZS55KSAlPiUgCiAgcmVuYW1lKGNvbmQxX2Rvc2UgPSBEb3NlLngsCiAgICAgICAgIGNvbmQyX2Rvc2UgPSBEb3NlLnkpICU+JSAKICBmaWx0ZXIoU2hhcmVkICE9IDApCgpjaXJjb3NfYWxsZG9zZXNfbWlycm9yID0gY2lyY29zX2FsbGRvc2VzICU+JSAKICBtdXRhdGUoQ29uZDFBID0gQ29uZDIsCiAgICAgICAgIENvbmQyQSA9IENvbmQxKSAlPiUgCiAgc2VsZWN0KENvbmQxQSwgQ29uZDJBLCBTaGFyZWQsIGNvbmQxX2Rvc2UsIGNvbmQyX2Rvc2UpICU+JSAKICByZW5hbWUoQ29uZDEgPSBDb25kMUEsCiAgICAgICAgIENvbmQyID0gQ29uZDJBKSAlPiUgCiAgcmJpbmQoY2lyY29zX2FsbGRvc2VzKQoKd3JpdGUuY3N2KGNpcmNvc19hbGxkb3Nlc19taXJyb3IsIGZpbGUgPSAiQ2lyY29zX0RPV05fQWxsZG9zZXNfcHZhbHVlMTBfZG9zZTEuY3N2IikKCgojRG9zZSAxCmNpcmNvc19kb3NlMSA9IHNoYXJlZF9nZW5lc19kZl9taXJyb3JfcDEwICU+JSAKICBzZWxlY3QoQ29uZDEsIENvbmQyLCBTaGFyZWQpICU+JSAKICBtdXRhdGUoU2hhcmVkID0gYXMubnVtZXJpYyhTaGFyZWQpKSAlPiUgIAogIG1lcmdlKGFubl92YWNjaW5lcywgYnkueCA9ICJDb25kMSIsIGJ5Lnk9IkNvbmRpdGlvbiIsIGFsbC54PVQsIGFsbC55PUYpICU+JQogIG1lcmdlKGFubl92YWNjaW5lcywgYnkueCA9ICJDb25kMiIsIGJ5Lnk9IkNvbmRpdGlvbiIsIGFsbC54PVQsIGFsbC55PUYpICU+JSAKICBzZWxlY3QoQ29uZDEsIENvbmQyLCBTaGFyZWQsRG9zZS54LCBEb3NlLnkpICU+JSAKICByZW5hbWUoY29uZDFfZG9zZSA9IERvc2UueCwKICAgICAgICAgY29uZDJfZG9zZSA9IERvc2UueSkgJT4lIAogIGZpbHRlcihjb25kMV9kb3NlID09IDEsCiAgICAgICAgIGNvbmQyX2Rvc2UgPT0gMSkKCmNpcmNvc19kb3NlMV9taXJyb3IgPSBjaXJjb3NfZG9zZTEgJT4lIAogIG11dGF0ZShDb25kMUEgPSBDb25kMiwKICAgICAgICAgQ29uZDJBID0gQ29uZDEpICU+JSAKICBzZWxlY3QoQ29uZDFBLCBDb25kMkEsIFNoYXJlZCwgY29uZDFfZG9zZSwgY29uZDJfZG9zZSkgJT4lIAogIHJlbmFtZShDb25kMSA9IENvbmQxQSwKICAgICAgICAgQ29uZDIgPSBDb25kMkEpICU+JSAKICByYmluZChjaXJjb3NfZG9zZTEpCgp3cml0ZS5jc3YoY2lyY29zX2Rvc2UxX21pcnJvciwgZmlsZSA9ICJDaXJjb3NfRE9XTl9wdmFsdWUxMF9kb3NlMS5jc3YiKQoKI0Rvc2UgMgpjaXJjb3NfZG9zZTIgPSBzaGFyZWRfZ2VuZXNfZGZfbWlycm9yX3AxMCAlPiUgCiAgc2VsZWN0KENvbmQxLCBDb25kMiwgU2hhcmVkKSAlPiUgCiAgbXV0YXRlKFNoYXJlZCA9IGFzLm51bWVyaWMoU2hhcmVkKSkgJT4lICAKICBtZXJnZShhbm5fdmFjY2luZXMsIGJ5LnggPSAiQ29uZDEiLCBieS55PSJDb25kaXRpb24iLCBhbGwueD1ULCBhbGwueT1GKSAlPiUKICBtZXJnZShhbm5fdmFjY2luZXMsIGJ5LnggPSAiQ29uZDIiLCBieS55PSJDb25kaXRpb24iLCBhbGwueD1ULCBhbGwueT1GKSAlPiUgCiAgc2VsZWN0KENvbmQxLCBDb25kMiwgU2hhcmVkLERvc2UueCwgRG9zZS55KSAlPiUgCiAgcmVuYW1lKGNvbmQxX2Rvc2UgPSBEb3NlLngsCiAgICAgICAgIGNvbmQyX2Rvc2UgPSBEb3NlLnkpICU+JSAKICBmaWx0ZXIoY29uZDFfZG9zZSA9PSAyLAogICAgICAgICBjb25kMl9kb3NlID09IDIpCmNpcmNvc19kb3NlMl9taXJyb3IgPSBjaXJjb3NfZG9zZTIgJT4lIAogIG11dGF0ZShDb25kMUEgPSBDb25kMiwKICAgICAgICAgQ29uZDJBID0gQ29uZDEpICU+JSAKICBzZWxlY3QoQ29uZDFBLCBDb25kMkEsIFNoYXJlZCwgY29uZDFfZG9zZSwgY29uZDJfZG9zZSkgJT4lIAogIHJlbmFtZShDb25kMSA9IENvbmQxQSwKICAgICAgICAgQ29uZDIgPSBDb25kMkEpICU+JSAKICByYmluZChjaXJjb3NfZG9zZTIpIAoKd3JpdGUuY3N2KGNpcmNvc19kb3NlMl9taXJyb3IsIGZpbGUgPSAiQ2lyY29zX0RPV05fcHZhbHVlMTBfZG9zZTIuY3N2IikKCiNEb3NlIDMKY2lyY29zX2Rvc2UzID0gc2hhcmVkX2dlbmVzX2RmX21pcnJvcl9wMTAgJT4lIAogIHNlbGVjdChDb25kMSwgQ29uZDIsIFNoYXJlZCkgJT4lIAogIG11dGF0ZShTaGFyZWQgPSBhcy5udW1lcmljKFNoYXJlZCkpICU+JSAgCiAgbWVyZ2UoYW5uX3ZhY2NpbmVzLCBieS54ID0gIkNvbmQxIiwgYnkueT0iQ29uZGl0aW9uIiwgYWxsLng9VCwgYWxsLnk9RikgJT4lCiAgbWVyZ2UoYW5uX3ZhY2NpbmVzLCBieS54ID0gIkNvbmQyIiwgYnkueT0iQ29uZGl0aW9uIiwgYWxsLng9VCwgYWxsLnk9RikgJT4lIAogIHNlbGVjdChDb25kMSwgQ29uZDIsIFNoYXJlZCxEb3NlLngsIERvc2UueSkgJT4lIAogIHJlbmFtZShjb25kMV9kb3NlID0gRG9zZS54LAogICAgICAgICBjb25kMl9kb3NlID0gRG9zZS55KSAlPiUgCiAgZmlsdGVyKGNvbmQxX2Rvc2UgPT0gMywKICAgICAgICAgY29uZDJfZG9zZSA9PSAzKQoKIGNpcmNvc19kb3NlM19taXJyb3IgPSBjaXJjb3NfZG9zZTMgJT4lIAogIG11dGF0ZShDb25kMUEgPSBDb25kMiwKICAgICAgICAgQ29uZDJBID0gQ29uZDEpICU+JSAKICBzZWxlY3QoQ29uZDFBLCBDb25kMkEsIFNoYXJlZCwgY29uZDFfZG9zZSwgY29uZDJfZG9zZSkgJT4lIAogIHJlbmFtZShDb25kMSA9IENvbmQxQSwKICAgICAgICAgQ29uZDIgPSBDb25kMkEpICU+JSAKICByYmluZChjaXJjb3NfZG9zZTMpIAoKd3JpdGUuY3N2KGNpcmNvc19kb3NlM19taXJyb3IsIGZpbGUgPSAiQ2lyY29zX0RPV05fcHZhbHVlMTBfZG9zZTMuY3N2IikKCmBgYAoKIyMjIFZpc3VhbGl6YcOnw6NvCgpEb3RwbG90CgpgYGB7cn0KIyMjIyBJZGVudGlkYWRlIGUgLWxvZyhxKQppbnN0YWxsLnBhY2thZ2VzKCJnZ2RlbmRybyIpCmxpYnJhcnkoZ2dkZW5kcm8pCmxpYnJhcnkoY293cGxvdCkKbGlicmFyeShnZ3RyZWUpCmxpYnJhcnkocGF0Y2h3b3JrKSAKCiNGaWx0cmFyIHZhbG9yZXMgY29tIC1sb2cocCkgPj0gMQpzaGFyZWRERUdzX1VQX0RPV05fZmlzaGVyX2ZpbHRlcmVkIDwtIHNoYXJlZERFR3NfVVBfRE9XTl9maXNoZXIgJT4lCiAgbXV0YXRlKGBTaWduaWZpY2FuY2UgLWxvZyhwKWAgPSBjdXQoYC1sb2cocClgLCAKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygtSW5mLCAxLCAxLjMsIDIsIEluZiksIAogICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCI8MSIsICIxLTEuMyIsICIxLjMtMiIsICI+MiIpKSkgJT4lCiAgZmlsdGVyKFBlcmNlbnRhZ2VfU2hhcmVkX0NvbmQxID49IDEsIFBlcmNlbnRhZ2VfU2hhcmVkX0NvbmQyID49IDEsIGBTaWduaWZpY2FuY2UgLWxvZyhwKWAgIT0gIjwxIikKCiNTYWx2YXIKd3JpdGUuY3N2KHNoYXJlZERFR3NfVVBfRE9XTl9maXNoZXJfZmlsdGVyZWQsIGZpbGUgPSAic2hhcmVkREVHc19VUF9ET1dOX2Zpc2hlcl9maWx0ZXJlZC5jc3YiKQoKI1Zpc3VhbGl6YXIKcGxvdCA9IGdncGxvdChzaGFyZWRERUdzX1VQX0RPV05fZmlzaGVyLCBhZXMoeCA9IENvbmQxLCB5ID0gQ29uZDIsIGNvbG9yID0gUGVyY2VudGFnZV9TaGFyZWRfQ29uZDEsIHNpemUgPSBQZXJjZW50YWdlX1NoYXJlZF9Db25kMSkpICsgCiAgZ2VvbV9wb2ludCgpICsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDIsIDgpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNwcmludGYoIiUuZiIsIFBlcmNlbnRhZ2VfU2hhcmVkX0NvbmQxKSksIHZqdXN0ID0gMC41LCBoanVzdCA9IDAuNSwgc2l6ZSA9IDIsIGNvbG9yID0gImJsYWNrIikgICsKICBjb3dwbG90Ojp0aGVtZV9jb3dwbG90KCkgKyAKICB0aGVtZShheGlzLmxpbmUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgdmp1c3QgPSAxLCBoanVzdCA9IDEsIHNpemUgPSAxMCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50KGxvdyA9ICJ3aGl0ZSIsIGhpZ2ggPSAiI2VmMjMzYyIsIGxpbWl0cyA9IGMoMCwgNjApKSArCiAgZ2d0aXRsZSgiJUlkZW50aXR5IGJldHdlZW4gdmFjY2luZXMsIFVwIGFuZCBEb3duLVJlZ3VsYXRlZCwgcHZhbHVlIDwgMC4wNSIgKSArCiAgeWxhYignQ29uZDInKSArCiAgdGhlbWUoYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGd1aWRlcyhjb2xvciA9IEZBTFNFLCBzaXplID0gRkFMU0UpCgojU2FsdmFyCmdnc2F2ZShwbG90LCBmaWxlID0gInNoYXJlZERFR3NfVVBfRE9XTl9maXNoZXIucG5nIikKCiNEaXNwbGF5CnBsb3QKYGBgCgoKCgoKCiMgU2luZ2xlIFNhbXBsZSBHU0VBIChzc0dTRUEpCiMjIEltbXVuZUdPCmBgYHtyfQpsaWJyYXJ5KGNvcnRvKQojIyMjIyMjIyMjIyMjIyBBcnF1aXZvcyBuZWNlc3PDoXJpb3MKCiNDZWxsTWFya2VyX0ltbXVuZUNlbGxzLmNzdiAKI0ltbXVuZUdPX0Fubm90YXRlZF9HZW5lc19OZXN0ZWRfSW50ZXJlc3RpbmcuY3N2CmFubl92YWNjaW5lcyAjQW5vdGHDp8OjbyBkYXMgdmFjaW5hcwoKIyMjIyMjIyMjIyMjIyMgR1NFMTk5NzUwCmdzZTE5OTc1MF9tZXRhZGF0YV9hbm5vdGF0ZWQJPSBnc2UxOTk3NTBfbWV0YWRhdGFfYW5ub3RhdGVkXzE2XzExXzIzICU+JSAKICBtdXRhdGUoY29uZGl0aW9uID0gY2FzZV93aGVuKAogICAgY29uZGl0aW9uID09ICJCTlQgKFYxLCBENilCTlQiIH4gIkJOVCAoVjEsIEQ2KSIsCiAgICBjb25kaXRpb24gPT0gIkJOVCAoVjEsIEQ2KU1PIiB+ICJCTlQtTU8gKFYxLCBENikiLAogICAgVFJVRSB+IGNvbmRpdGlvbikpICU+JSAKICBzZWxlY3Qoc2FtcGxlLCBjb25kaXRpb24sIGdlbywgZGF5LCBkb3NlLCBhZ2UsIHNleCkKCiNTYWx2YXIKd3JpdGUuY3N2KGdzZTE5OTc1MF9tZXRhZGF0YV9hbm5vdGF0ZWQsIGZpbGUgPSAiZ3NlMTk5NzUwX21ldGFkYXRhX2Fubm90YXRlZF8yMi0xMS0yMy5jc3YiKQoKZ3NlMTk5NzUwX2NvdW50c19yZWFkeSAjbWF0cml6IGRlIGV4cHJlc3PDo28KCgojIyMjIyMjIyMjIyMjIyBHU0UyMDE1MzMKCmdzZTIwMTUzM19tZXRhZGF0YV9hbm5vdGF0ZWQgPSBnc2UyMDE1MzNfbWV0YWRhdGFfbG9uZ19hbm5vdGF0ZWRfMTRfMTFfMjMgJT4lICNNZXRhZGFkb3MKICBzZWxlY3QoY29uZGl0aW9uOnZhY2NpbmUpCgpnc2UyMDE1MzNfY291bnRzX3JlYWR5ICNNYXRyaXogZGUgZXhwcmVzc8OjbwoKCiMjIyMjIyMjIyMjIyMjIEdTRTIwNjAyMwpnc2UyMDYwMjNfbWV0YWRhdGFfcmVhZHkgPSBnc2UyMDYwMjNfY291bnRzX2xvbmdfYW5ub3RhdGVkXzE0XzExXzIzICU+JSAgI01ldGFkYWRvcwogIHNlbGVjdChjb25kaXRpb246YWdlKSAlPiUgCiAgZGlzdGluY3QoKSAlPiUgCiAgbXV0YXRlKHR5cGUgPSBpZl9lbHNlKHR5cGU9PSJITyIsICJJTiIsIHR5cGUpKQoKd3JpdGUuY3N2KGdzZTIwNjAyM19tZXRhZGF0YV9yZWFkeSwgZmlsZSA9ICJnc2UyMDYwMjNfbWV0YWRhdGFfcmVhZHkuY3N2IikKCiNNYXRyaXogZGUgZXhwcmVzc8Ojbwpnc2UyMDYwMjNfY291bnRzX3JlYWR5ID0gZ3NlMjA2MDIzX2NvdW50c19sb25nX2Fubm90YXRlZF8xNF8xMV8yMyAlPiUgCiAgbXV0YXRlKGNvdW50cyA9IGFzLm51bWVyaWMoY291bnRzKSkgJT4lIAogIHNlbGVjdChnZW5lcywgc2FtcGxlLCBjb3VudHMpICU+JSAKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc2FtcGxlLCB2YWx1ZXNfZnJvbSA9IGNvdW50cywgdmFsdWVzX2ZuID0gbWVhbikgJT4lIAogIGNvbHVtbl90b19yb3duYW1lcygiZ2VuZXMiKQoKd3JpdGUuY3N2KGdzZTIwNjAyM19jb3VudHNfcmVhZHksIGZpbGUgPSAiZ3NlMjA2MDIzX2NvdW50c19yZWFkeS5yZHMiKQoKYGBgCgoKYGBge3J9CiMjIyMjIyMjIyMjIyMjIElucHV0cwoKc3Nnc2VhX2dlbmUgPSBnc2UyMDYwMjNfY291bnRzX3JlYWR5ICNDcmlhciB2YXJpw6F2ZWwKbWV0YWRhdGEgPSBnc2UyMDYwMjNfbWV0YWRhdGFfcmVhZHkKZmlsZW5hbWUgPSAiR1NFMjA2MDIzIgpnb19kYXRhc2V0ID0gIkNlbGxNYXJrZXIiCgojRXh0cmFpciBzYW1wbGUgbmFtZXMuIE8gc3NHU0VBIHBlcmRlIG8gbm9tZSBubyByZXN1bHRhZG8uCnNhbXBsZV9uYW1lcyA9IHNzZ3NlYV9nZW5lICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIGNvbG5hbWVzKCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKHNhbXBsZV9uYW1lcyA9ICcuJykKCiNUYWJlbGEgY29tIGdlbmVzIGRlIGludGVyZXNzZSAoZ2VyYWwpIGNvbnZlcnRpZGEgZW0gbGlzdGFzIAoKZ2VuZWxpc3QgPSBDZWxsTWFya2VyX0ltbXVuZUNlbGxzICU+JSAjQ2VsbE1hcmtlcl9JbW11bmVDZWxscy5jc3YKICBzZWxlY3QoY2VsbCA9IGNlbGxfbmFtZSwgZ2VuZXMgPSBtYXJrZXIpCmdlbmVsaXN0ID0gc3BsaXQoZ2VuZWxpc3QkZ2VuZXMsIGdlbmVsaXN0JGNlbGwpIAoKIyMjIyMjIyMjIyMjIyMgQW7DoWxpc2UgCgojIFJ1biBzc0dTRUEKbmVzbWF0ID0gc3Nnc2VhKHNzZ3NlYV9nZW5lLCBnZW5lbGlzdCkKCiNQYWRyb25pemFyIHJlc3VsdGFkbwpuZXNtYXQucmVzdWx0ID0gbmVzbWF0ICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIHQoKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByb3duYW1lc190b19jb2x1bW4oInNhbXBsZSIpICU+JSAKICByZWxvY2F0ZShzYW1wbGUsIC5iZWZvcmUgPSBldmVyeXRoaW5nKCkpICU+JSAKICBjYmluZChzYW1wbGVfbmFtZXMpICU+JSAKICBzZWxlY3QoLXNhbXBsZSkgJT4lIAogIGNvbHVtbl90b19yb3duYW1lcygic2FtcGxlX25hbWVzIikgJT4lIAogIHQoKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByb3duYW1lc190b19jb2x1bW4oInByb2Nlc3MiKSAlPiUgCiAgcmVsb2NhdGUocHJvY2VzcywgLmJlZm9yZT1ldmVyeXRoaW5nKCkpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IC1wcm9jZXNzLCBuYW1lc190byA9ICJzYW1wbGUiLCB2YWx1ZXNfdG8gPSAibmVzIikgJT4lIAogIG11dGF0ZShwdmFsdWUgPSB6MnAobmVzKSwgI0NvbnZlcnRlciBORVMgZW0gcHZhbHVlCiAgICAgICAgIHF2YWx1ZSA9IHAuYWRqdXN0KHB2YWx1ZSwgbWV0aG9kID0gIkJIIiksICNhanVzdGFyIHBhcmEgcXZhbHVlIAogICAgICAgICBsb2dxID0gLSBsb2cxMChxdmFsdWUpKSAlPiUgICNDYWxjdWxhciAtbG9nKHEpCiAgbWVyZ2UobWV0YWRhdGEsIGJ5PSJzYW1wbGUiLCBhbGwueD1UKSAlPiUgI1VuaXIgY29tIG1ldGFkYXRhCiAgbXV0YXRlKHN0dWR5ID0gZmlsZW5hbWUpICU+JSAKICBtZXJnZShDZWxsTWFya2VyX0ltbXVuZUNlbGxzLCBieS54ID0icHJvY2VzcyIsIGJ5LnkgPSAiY2VsbF9uYW1lIiwgYWxsLng9VCkgJT4lIAogIHNlbGVjdCgtIi4uLjEiKSAlPiUgCiAgcmVuYW1lKGNlbGxfbmFtZSA9IHByb2Nlc3MpCgojU2FsdmFyCndyaXRlLmNzdihuZXNtYXQucmVzdWx0LCBmaWxlID0gcGFzdGUwKGZpbGVuYW1lLCBzZXAgPSAiXyIsIGdvX2RhdGFzZXQsICJfc3Nnc2VhX3Jlc3VsdC5jc3YiKSkKCnByaW50KG5lc21hdC5yZXN1bHQpCmBgYAoKKlVuaXIgcmVzdWx0YWRvcyoKCmBgYHtyfQoKIyMjIyMjIyMjIyMjIyMjIFVuaXIgcmVzdWx0YWRvcwpHU0UxOTk3NTBfQ2VsbE1hcmtlcl9zc2dzZWFfcmVzdWx0ID0gR1NFMTk5NzUwX0NlbGxNYXJrZXJfc3Nnc2VhX3Jlc3VsdCAlPiUKICBjbGVhbl9uYW1lcygpICU+JSAKICBzZWxlY3QoY2VsbF9uYW1lOnR5cGUsIC1tYXJrZXIpICU+JSAKICBkaXN0aW5jdCgpCgpHU0UyMDE1MzNfQ2VsbE1hcmtlcl9zc2dzZWFfcmVzdWx0ID0gR1NFMjAxNTMzX0NlbGxNYXJrZXJfc3Nnc2VhX3Jlc3VsdCAlPiUgCiAgY2xlYW5fbmFtZXMoKSAlPiUgCiAgc2VsZWN0KGNlbGxfbmFtZTp0eXBlLCAtbWFya2VyKSAlPiUgCiAgZGlzdGluY3QoKQoKR1NFMjA2MDIzX0NlbGxNYXJrZXJfc3Nnc2VhX3Jlc3VsdCA9IEdTRTIwNjAyM19DZWxsTWFya2VyX3NzZ3NlYV9yZXN1bHQgJT4lIAogIGNsZWFuX25hbWVzKCkgJT4lIAogIHNlbGVjdChjZWxsX25hbWU6dHlwZSwgLW1hcmtlcikgJT4lIAogIGRpc3RpbmN0KCkgCiAgCiAgCkdTRTIwNjAyM19DZWxsTWFya2VyX3NzZ3NlYV9yZXN1bHQgPSBHU0UyMDYwMjNfQ2VsbE1hcmtlcl9zc2dzZWFfcmVzdWx0ICU+JSAKICBtdXRhdGUoYWdlID0gYXMuZG91YmxlKGFnZSkpCgpzc2dzZWFfcmVzdWx0c191bmlmaWVkID0gYmluZF9yb3dzKEdTRTE5OTc1MF9DZWxsTWFya2VyX3NzZ3NlYV9yZXN1bHQsCiAgICAgICAgICBHU0UyMDE1MzNfQ2VsbE1hcmtlcl9zc2dzZWFfcmVzdWx0LAogICAgICAgICAgR1NFMjA2MDIzX0NlbGxNYXJrZXJfc3Nnc2VhX3Jlc3VsdCkKCnNzZ3NlYV9yZXN1bHRzX3VuaWZpZWQgPSBzc2dzZWFfcmVzdWx0c191bmlmaWVkICU+JSAKICBzZWxlY3QoY2VsbF9uYW1lOmltbXVuZV9zeXN0ZW0pICU+JSAKICBtZXJnZShhbm5fdmFjY2luZXMsIGJ5LnggPSAiY29uZGl0aW9uIiwgYnkueSA9ICJDb25kaXRpb24iKQoKI1NhbHZhcgp3cml0ZS5jc3Yoc3Nnc2VhX3Jlc3VsdHNfdW5pZmllZCwgZmlsZSA9IHBhc3RlMChnb19kYXRhc2V0LCAiX3NzZ3NlYV9yZXN1bHRzX3VuaWZpZWQuY3N2IikpCgpgYGAKCgojIyMgVmlzdWFsaXphw6fDo28KCmBgYHtyfQoKIyBJTlBVVApuZXNtYXQucmVzdWx0ID0gR1NFMTk5NzUwX3NzZ3NlYV9yZXN1bHQKZmlsZW5hbWUgPSAiR1NFMTk5NzUwIgoKI0ZpbHRyYXIKCiNMaXN0YSBkZSBwcm9jZXNzb3MKCnNzZ3NlYV9pbnRlcmVzdGluZyA9IG5lc21hdC5yZXN1bHQgJT4lIAogIGZpbHRlcihwdmFsdWUgPD0gMC4xMCkgJT4lIAogIGRpc3RpbmN0KCkKCiNCb3hwbG90IChORVMpCk5FU19wbG90ID0gZ2dwbG90KHNzZ3NlYV9pbnRlcmVzdGluZykgKwogIGFlcyh4ID0gY29uZGl0aW9uLCB5ID0gbmVzLCBmaWxsID0gdmFjY2luZSkgKwogIGdlb21fYm94cGxvdCgpICsKICBzY2FsZV9maWxsX2h1ZShkaXJlY3Rpb24gPSAxKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBmYWNldF9ncmlkKHZhcnMocHJvY2VzcyksIHZhcnModmFjY2luZSksIHNjYWxlcyA9ICJmcmVlX3giKSArCiBsYWJzKHRpdGxlID0gcGFzdGUwKGZpbGVuYW1lLCAiX0ltbXVuZUdPIHNzR1NFQSIpLCAKICAgICAgZmlsbCA9ICJ2YWNjaW5lIikgKwogdGhlbWVfYncoKSArCiB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMEwsIGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSwKICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHZqdXN0ID0gMSwgaGp1c3Q9MSwgc2l6ZSA9IDcpKSAKCiNTYWx2YXIKZ2dzYXZlKE5FU19wbG90LCBmaWxlPSBwYXN0ZTAoZmlsZW5hbWUsICJfc3NHU0VBX05FU19xdmFsdWUwMTAucG5nIiksIHdpZHRoID0gMTAsIGhlaWdodCA9IDIwKQpgYGAKCgpgYGB7cn0Kc3Nnc2VhX2ludGVyZXN0aW5nLnVuaWZpZWQgPSBzc2dzZWFfcmVzdWx0c191bmlmaWVkICU+JSAKICBmaWx0ZXIoIWNvbmRpdGlvbiAlaW4lIGMoIkJOVC1NTyAoVjEsIEQwKSIsICJCTlQtTU8gKFYyLCBEMCkiKSkgJT4lIAogIG11dGF0ZShkYXkgPSBhcy5mYWN0b3IoZGF5KSwKICAgICAgICAgZG9zZSA9IGFzLmZhY3Rvcihkb3NlKSkKCnNzZ3NlYV9pbnRlcmVzdGluZy5nZW5lcmFsLnVuaWZpZWQgPSBzc2dzZWFfaW50ZXJlc3RpbmcudW5pZmllZCAlPiUgCiAgZmlsdGVyKHByb2Nlc3MgJWluJSBjKCJBREFQVElWRSBJTU1VTkUgU1lTVEVNIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICJDRUxMVUxBUiBBREFQVElWRSBJTU1VTkUgU1lTVEVNIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICJJTk5BVEUgSU1NVU5FIFNZU1RFTSIsIAogICAgICAgICAgICAgICAgICAgICAgICAiSU5GTEFNTUFUSU9OIiksCiAgICAgICAgIHB2YWx1ZSA8PSAwLjEwKQoKc3Nnc2VhX2ludGVyZXN0aW5nLnNwZWNpZmljLnVuaWZpZWQgPSBzc2dzZWFfaW50ZXJlc3RpbmcudW5pZmllZCAlPiUgCiAgZmlsdGVyKCFwcm9jZXNzICVpbiUgYygiQURBUFRJVkUgSU1NVU5FIFNZU1RFTSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIkNFTExVTEFSIEFEQVBUSVZFIElNTVVORSBTWVNURU0iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICJJTk5BVEUgSU1NVU5FIFNZU1RFTSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIklORkxBTU1BVElPTiIpLAogICAgICAgICBwdmFsdWUgPD0gMC4xMCkKCgpkYXRhID0gc3Nnc2VhX3Jlc3VsdHNfdW5pZmllZApmaWxlbmFtZS51bmlmaWVkID0gInNzZ3NlYV9yZXN1bHRzX3VuaWZpZWQiCmBgYAoKCmBgYHtyfQojQWxsIGNvbmRpdGlvbnMgZGl2aWRlZCBieSBkb3NlLCB0aW1lIG9uIHgtYXhpcwoKIyBGaWx0cmFyIG9zIGRhZG9zIGFudGVzIGRlIHBhc3NhciBwYXJhIGdncGxvdApmaWx0ZXJlZF9kYXRhIDwtIGRhdGEgJT4lCiAgZ3JvdXBfYnkoY2VsbF9uYW1lLCBWYWNjaW5lLCBjb25kaXRpb24pICU+JQogIHN1bW1hcmlzZShuID0gbigpKSAlPiUKICBmaWx0ZXIobiA8IDUpICU+JQogIHB1bGwoY29uZGl0aW9uKQoKCk5FU19wbG90X3VuaWZpZWRfZGF5eCA8LSBnZ3Bsb3QoZGF0YSkgKwogIGFlcyh4ID0gZGF5LCB5ID0gbmVzLCBmaWxsID0gVmFjY2luZSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLmFscGhhID0gMSkgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN1YnNldChkYXRhLCBkYXkgJWluJSBmaWx0ZXJlZF9kYXRhKSwKICAgICAgICAgICAgIGFlcyh4ID0gZGF5LCB5ID0gbmVzLCBjb2xvciA9IFZhY2NpbmUpLAogICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjIpLCBhbHBoYSA9IDEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB2YXhjb2xvcnMpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhCQklCUCA9ICIjZmZkMDAwIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWkYyMDAxID0gIiNiNTE3OWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJOVCA9ICIjNTZjZmUxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDaEFkID0gIiM4MGZmZGIiICwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2hBZC1CTlQiID0gIiM3MmVmZGQiKSkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJzc0dTRUEgLSBBbGwgc3R1ZGllcyIsCiAgICBzdWJ0aXRsZSA9ICJHZW5lcmFsIEltbXVuZUdPLCBieSBkb3NlIiwKICAgIGNhcHRpb24gPSAiVmFjY2luZSIsCiAgICBmaWxsID0gIlZhY2NpbmVzIgogICkgKyAKICB0aGVtZV9taW5pbWFsKCkgKwogIGZhY2V0X2dyaWQodmFycyhUeXBlKSwgdmFycyhkb3NlKSwgc2NhbGVzID0gImZyZWVfeCIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMEwsIGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSwKICAgICAgICBzdHJpcC50ZXh0LnkgPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCB2anVzdCA9IDEsIGhqdXN0ID0gMSwgc2l6ZSA9IDUpLAogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQoKI1NhbHZhcgpnZ3NhdmUoTkVTX3Bsb3RfdW5pZmllZF9kYXl4LCBmaWxlID0gcGFzdGUwKGZpbGVuYW1lLnVuaWZpZWQsICJfc3NHU0VBX05FU19xdmFsdWUwMTBfMi5wbmciKSwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gMTApCgpwcmludChORVNfcGxvdF91bmlmaWVkX2RheXgpCgpgYGAKCgoKYGBge3J9CiNBbGwgY29uZGl0aW9ucyBkaXZpZGVkIGJ5IHZhY2NpbmUsIHRpbWUgb24geC1heGlzCgojIENyaWFyIG8gZ3LDoWZpY28KTkVTX3Bsb3RfdW5pZmllZF9kYXl4X3ZheCA8LSBnZ3Bsb3QoZGF0YSkgKwogIGFlcyh4ID0gY29uZGl0aW9uLCB5ID0gbmVzLCBmaWxsID0gZG9zZSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLmFscGhhID0gMC41KSArCiAgZ2VvbV9wb2ludChkYXRhID0gc3Vic2V0KGRhdGEsIGNvbmRpdGlvbiAlaW4lIGZpbHRlcmVkX2RhdGEpLAogICAgICAgICAgICAgYWVzKHggPSBjb25kaXRpb24sIHkgPSBuZXMsIGNvbG9yID0gImJsYWNrIiksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IDAuMiksIGFscGhhID0gMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGRvc2VfY29sb3JzKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGRvc2VfY29sb3JzKSArCiAgbGFicygKICAgIHRpdGxlID0gInNzR1NFQSAtIEFsbCBzdHVkaWVzIiwKICAgIHN1YnRpdGxlID0gIkdlbmVyYWwgSW1tdW5lR08sIGJ5IGRvc2UiLAogICAgY2FwdGlvbiA9ICJWYWNjaW5lIiwKICAgIGZpbGwgPSAiVmFjY2luZXMiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBmYWNldF9ncmlkKHZhcnMocHJvY2VzcyksIHZhcnModmFjY2luZSksIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjBMLCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDEsIGhqdXN0ID0gMSwgc2l6ZSA9IDcpLAogICAgc3RyaXAudGV4dC55ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgdmp1c3QgPSAxLCBoanVzdCA9IDEsIHNpemUgPSA3KSAgIyBSb3Rhw6fDo28gZG8gdGV4dG8gZGEgZmFjZXQgcm93CiAgKQoKI1NhbHZhcgpnZ3NhdmUoTkVTX3Bsb3RfdW5pZmllZF9kYXl4X3ZheCwgZmlsZSA9IHBhc3RlMChmaWxlbmFtZS51bmlmaWVkLCAiX3NzR1NFQV9ORVNfcXZhbHVlMDEwXzMucG5nIiksIHdpZHRoID0gMjAsIGhlaWdodCA9IDIwKQoKcHJpbnQoTkVTX3Bsb3RfdW5pZmllZF9kYXl4X3ZheCkKYGBgCgoKCgoKIyMjICBBbmFsaXNlIGVzdGF0w61zdGljYQoKYGBge3J9Cmluc3RhbGwucGFja2FnZXMoImdnc3RhdHNwbG90IikKbGlicmFyeShnZ3N0YXRzcGxvdCkKCnNzZ3NlYV9pbnRlcmVzdGluZyA9IHNzZ3NlYV9pbnRlcmVzdGluZyAlPiUgCiAgZmlsdGVyKHByb2Nlc3MgPT0gIklOTkFURSBJTU1VTkUgU1lTVEVNIikgJT4lIAogIGRpc3RpbmN0KCkKCnByb2Nlc3MgPSAiSU5OQVRFIElNTVVORSBTWVNURU0iCgoKZ2diZXR3ZWVuc3RhdHMoCiAgZGF0YSAgPSBzc2dzZWFfaW50ZXJlc3RpbmcsCiAgeCAgICAgPSBjb25kaXRpb24sCiAgeSAgICAgPSBuZXMsCiAgdGl0bGUgPSAgcGFzdGUwKCJJbW11bmVHTyBzc0dTRUEgIiwgZmlsZW5hbWUsIHByb2Nlc3MpCikKCiNBZ3J1cGFkbwpncm91cGVkX2dnYmV0d2VlbnN0YXRzKAogIGRhdGEgICAgICAgICAgICAgPSBzc2dzZWFfaW50ZXJlc3RpbmcsCiAgeCAgICAgICAgICAgICAgICA9IGNvbmRpdGlvbiwKICB5ICAgICAgICAgICAgICAgID0gbmVzLAogIGdyb3VwaW5nLnZhciAgICAgPSBwcm9jZXNzLAogIGdnc2lnbmlmLmFyZ3MgICAgPSBsaXN0KHRleHRzaXplID0gNCwgdGlwX2xlbmd0aCA9IDAuMDEpLAogIHAuYWRqdXN0Lm1ldGhvZCAgPSAiYm9uZmVycm9uaSIsCiAgcGFsZXR0ZSAgICAgICAgICA9ICJkZWZhdWx0X2phbWEiLAogIHBhY2thZ2UgICAgICAgICAgPSAiZ2dzY2kiLAogIHBsb3RncmlkLmFyZ3MgICAgPSBsaXN0KG5yb3cgPSAxKSwKICBhbm5vdGF0aW9uLmFyZ3MgID0gbGlzdCh0aXRsZSA9IHBhc3RlMCgiSW1tdW5lR08gc3NHU0VBICIsIGZpbGVuYW1lKSkKKQoKYGBgCgoKIyMjIEFOT1ZBCgpgYGB7cn0KZXNxdWlzc2VyKHRlc3QpCgpsaWJyYXJ5KGdnc2lnbmlmKQpsaWJyYXJ5KHJzdGF0aXgpCgpkZiA9IHRlc3QKZGYkQ29uZGl0aW9uIDwtIGFzLmZhY3RvcihkZiRDb25kaXRpb24pCgpzdGF0LnRlc3QgPC0gZGYgJT4lCiAgdF90ZXN0KENvbmRpdGlvbiB+IE5FUykgJT4lCiAgYWRkX3NpZ25pZmljYW5jZSgpCgoKdGVzdCAlPiUKICBmaWx0ZXIoUHJvY2VzcyAlaW4lICJJTk5BVEUgSU1NVU5FIFJFU1BPTlNFIikgJT4lCiAgZ2dib3hwbG90KHggPSAiUHJvY2VzcyIsIHkgPSAiTkVTIiwKICAgICAgICAgIGNvbG9yID0gIkNvbmRpdGlvbiIsIHBhbGV0dGUgPSAiamNvIikgKwogIGZhY2V0X3dyYXAodmFycyhWYWNjaW5lKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAiYW5vdmEiLCBsYWJlbC55ID0gNCkgKyAgICAgICMgQWRkIGdsb2JhbCBwLXZhbHVlCiAgc3RhdF9jb21wYXJlX21lYW5zKGxhYmVsID0gInAuc2lnbmlmIiwgbWV0aG9kID0gInQudGVzdCIsCiAgICAgICAgICAgICAgICAgICAgIHJlZi5ncm91cCA9ICIuYWxsLiIpICAgICMgQ29tcGFyYcOnw6NvIG3Dumx0aXBsYSB1c2FuZG8gVHVrZXkgSFNECgoKIyBCb3ggcGxvdHMgd2l0aCBwLXZhbHVlcwpieHAgPC0gZ2dib3hwbG90KGRmLCB4ID0gIlByb2Nlc3MiLCB5ID0gIk5FUyIsIGZpbGwgPSAiIzAwQUZCQiIpCnN0YXQudGVzdCA8LSBzdGF0LnRlc3QgJT4lIGFkZF94eV9wb3NpdGlvbih4ID0gInN1cHAiKQpieHAgKyAKICBzdGF0X3B2YWx1ZV9tYW51YWwoc3RhdC50ZXN0LCBsYWJlbCA9ICJwIikgKwogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBleHBhbnNpb24obXVsdCA9IGMoMC4wNSwgMC4xKSkpCgpgYGAKCiMjIyBQQ0EKCjxodHRwczovL3d3dy5kYXRhY2FtcC5jb20vdHV0b3JpYWwvcGNhLWFuYWx5c2lzLXI+IAo8aHR0cHM6Ly9ycGtncy5kYXRhbm92aWEuY29tL2ZhY3RvZXh0cmEvaW5kZXguaHRtbD4gPGh0dHA6Ly93d3cuc3RoZGEuY29tL2VuZ2xpc2gvYXJ0aWNsZXMvMzEtcHJpbmNpcGFsLWNvbXBvbmVudC1tZXRob2RzLWluLXItcHJhY3RpY2FsLWd1aWRlLzExNC1tY2EtbXVsdGlwbGUtY29ycmVzcG9uZGVuY2UtYW5hbHlzaXMtaW4tci1lc3NlbnRpYWxzLz4KPGh0dHBzOi8vc3RhdGlzdGljc2dsb2JlLmNvbS9wY2EtYmVmb3JlLWstbWVhbnMtY2x1c3RlcmluZy1yPj4KCkJpYmxpb3RlY2FzCmBgYHtyfQpsaWJyYXJ5KGZhY3RvZXh0cmEpCmxpYnJhcnkoY2FyZXQpCmxpYnJhcnkoc3RhdHMpCmxpYnJhcnkoZ2dmb3J0aWZ5KQpsaWJyYXJ5KGdncGxvdDIpCmBgYAoKIyMjIyBCeSBHTyB0ZXJtCgpgYGB7cn0KCnNzZ3NlYV9yZXN1bHRzX3VuaWZpZWQgPSBzc2dzZWFfcmVzdWx0c191bmlmaWVkICU+JSBkaXN0aW5jdCgpIAogIApzc2dzZWFfcmVzdWx0c191bmlmaWVkLmlubmF0ZSA9IHNzZ3NlYV9yZXN1bHRzX3VuaWZpZWQgJT4lIAogIGZpbHRlcihwcm9jZXNzICVpbiUgYygiSU5OQVRFIElNTVVORSBTWVNURU0iLCAiQU5USVZJUkFMIEFORCBJTlRFUkZFUk9OIiwgIkFSUFAiLCAiSU5GTEFNTUFUSU9OIiwgIkRFTkRSSVRJQyBDRUxMUyIsICJNQUNST1BIQUdFUyIpKQoKc3Nnc2VhX3Jlc3VsdHNfdW5pZmllZC5hZGFwdGl2ZSA9IHNzZ3NlYV9yZXN1bHRzX3VuaWZpZWQgJT4lIAogIGZpbHRlcighcHJvY2VzcyAlaW4lIGMoIklOTkFURSBJTU1VTkUgU1lTVEVNIiwgIkFOVElWSVJBTCBBTkQgSU5URVJGRVJPTiIsICJBUlBQIiwgIklORkxBTU1BVElPTiIsICJERU5EUklUSUMgQ0VMTFMiLCAiTUFDUk9QSEFHRVMiKSkgJT4lIAogIGZpbHRlcighc3R1ZHkgPT0gIkdTRTIwMTUzMyIpCiAgCgpgYGAKCgpgYGB7cn0KZGF0YV9JbW11bmVHTyA9IHNzZ3NlYV9yZXN1bHRzX3VuaWZpZWQuYWRhcHRpdmUgCmZpbGVuYW1lID0gInNzZ3NlYV9yZXN1bHRzX3VuaWZpZWQuYWRhcHRpdmUiCgpwY2FfYW5uID0gZGF0YV9JbW11bmVHTyAlPiUgCiAgc2VsZWN0KHNhbXBsZSwgY29uZGl0aW9uLCB2YWNjaW5lLCBnZW86c2V4KQoKI0NvbnZlcnRlciBkZSBsb25nIHBhcmEgd2lkZQptYXRyaXhfZ2VuZXMgPSBkYXRhX0ltbXVuZUdPICU+JSAKICBzZWxlY3Qoc2FtcGxlLCBwcm9jZXNzLCBuZXMpCgptYXRyaXhfZ2VuZXMgPC0gZGNhc3QobWF0cml4X2dlbmVzLCBgc2FtcGxlYCB+IGBwcm9jZXNzYCwgCiAgICAgICAgICAgICAgICAgICAgIHZhbHVlLnZhciA9ICJuZXMiLCAKICAgICAgICAgICAgICAgICAgICAgZnVuLmFnZ3JlZ2F0ZSA9IG1lYW4pCgptYXRyaXhfZ2VuZXMgPC0gcmVwbGFjZShtYXRyaXhfZ2VuZXMsIG1hdHJpeF9nZW5lcyA9PSAiTmFOIiwgMCkgCgojQ29udmVydGVyIGNvbHVuYSAxIGVtIHJvd25hbWVzIGUgZXhjbHVpcgptYXRyaXhfZGF0YV9wY2EgPSBtYXRyaXhfZ2VuZXMgJT4lIAogIGFzLmRhdGEuZnJhbWUoKQoKbWF0cml4X2RhdGFfcGNhX3JlYWR5ID0gbWF0cml4X2RhdGFfcGNhICU+JSAgCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJzYW1wbGUiKQoKYW5uX3ZhY2NpbmVzX3BjYV9tYXRyaXggPSBtYXRyaXhfZGF0YV9wY2EgJT4lIAogIG1lcmdlKHBjYV9hbm4sIGJ5LnkgPSAic2FtcGxlIiwgYnkueCA9ICJzYW1wbGUiLCBhbGwueCA9IFQsIGFsbC55ID0gRikgJT4lIAogIGRpc3RpbmN0KCkKCmFubl92YWNjaW5lc19wY2FfbWF0cml4X3JlYWR5ID0gYW5uX3ZhY2NpbmVzX3BjYV9tYXRyaXggJT4lIAogIHNlbGVjdChzYW1wbGUsIGNvbmRpdGlvbiwgdmFjY2luZSwgZGF5LCBkb3NlKSAlPiUgCiAgbXV0YXRlKGRvc2UgPSBhcy5mYWN0b3IoZG9zZSksCiAgICAgICAgIGRheSA9IGFzLmZhY3RvcihkYXkpKQoKIyBWZXJpZmlxdWUgcXVhaXMgY29sdW5hcyB0w6ptIHZhcmnDom5jaWEgbXVpdG8gYmFpeGEKbmVhclplcm9WYXJDb2xzIDwtIG5lYXJaZXJvVmFyKG1hdHJpeF9kYXRhX3BjYV9yZWFkeSwgc2F2ZU1ldHJpY3MgPSBUUlVFKQptYXRyaXhfZGF0YV9wY2FfcmVhZHkgPC0gbWF0cml4X2RhdGFfcGNhX3JlYWR5WywgIW5lYXJaZXJvVmFyQ29scyRuenZdCnBjYV9yZXMgPC0gcHJjb21wKG1hdHJpeF9kYXRhX3BjYV9yZWFkeSwgc2NhbGUuID0gVFJVRSkKCiMgQ3JpZSBvIGdyw6FmaWNvIGRlIFBDQQoKIyMjIyMjIENvbmRpdGlvbgpwY2FfcGxvdF9jb25kaXRpb24gPSBhdXRvcGxvdChwY2FfcmVzLCAKICAgICAgICAgICAgICAgICAgICBkYXRhID0gYW5uX3ZhY2NpbmVzX3BjYV9tYXRyaXhfcmVhZHksIAogICAgICAgICAgICAgICAgICAgIGNvbG91ciA9ICdjb25kaXRpb24nLCAKICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IDApICsgCiAgbGFicyh0aXRsZT1wYXN0ZTAoZmlsZW5hbWUsICJfYnljb25kaXRpb24iKSkgKyAjc2NhbGUgZmlsbCBtYW51YWwKICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIikgKwogIHRoZW1lX21pbmltYWwoKQoKCiMjIyMjIyBWYWNjaW5lCnBjYV9wbG90X3ZhYyA9IGF1dG9wbG90KHBjYV9yZXMsIAogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBhbm5fdmFjY2luZXNfcGNhX21hdHJpeF9yZWFkeSwgCiAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gJ3ZhY2NpbmUnLCAKICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IDApICsgCiAgbGFicyh0aXRsZT1wYXN0ZTAoZmlsZW5hbWUsICJfYnl2YWNjaW5lIikpICsgI3NjYWxlIGZpbGwgbWFudWFsCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gYygKICAiQkJJQlAiID0gIiNmZmQwMDAiLAogICJCTlQiID0gIiM1NmNmZTEiLAogICJDaEFkIiA9ICIjODBmZmRiIiwKICAiQ2hBZC1CTlQiID0gIiMwMDc3YjYiLAogICJaRjIwMDEiID0gIiNiNTE3OWUiKSkgKwogIHRoZW1lX21pbmltYWwoKQoKIyMjIyMjIERheQpwY2FfcGxvdF9kYXkgPSBhdXRvcGxvdChwY2FfcmVzLCAKICAgICAgICAgICAgICAgICAgICBkYXRhID0gYW5uX3ZhY2NpbmVzX3BjYV9tYXRyaXhfcmVhZHksIAogICAgICAgICAgICAgICAgICAgIGNvbG91ciA9ICdkYXknLCAKICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IDApICsgCiAgbGFicyh0aXRsZT1wYXN0ZTAoZmlsZW5hbWUsICJfZGF5IikpICsgI3NjYWxlIGZpbGwgbWFudWFsCiAgIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgICB2YWx1ZXMgPSBjKAogICAgICAgIjAiID0gImdyZXk5MCIsCiAgICAiMSIgPSAiI2NhZjBmOCIsCiAgICAiMyIgPSAiIzkwZTBlZiIsCiAgICAiNiIgPSAiIzAwYjRkOCIsCiAgICAiNyIgPSAiIzAwNzdiNiIsCiAgICAiMTQiID0gIiMwMjNlOGEiLAogICAgIjI4IiA9ICIjMDMwNDVlIikpICsKICB0aGVtZV9taW5pbWFsKCkKCiMjIyMjIyBEb3NlCgpwY2FfcGxvdF9kb3NlID0gYXV0b3Bsb3QocGNhX3JlcywgCiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGFubl92YWNjaW5lc19wY2FfbWF0cml4X3JlYWR5LCAKICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAnZG9zZScsIAogICAgICAgICAgICAgICAgICAgIGxhYmVsID0gMCkgKyAKICBsYWJzKHRpdGxlPXBhc3RlMChmaWxlbmFtZSwgIl9kb3NlIikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKCIwIiA9ICIjY2FmMGY4IiwgCiAgICAgICAgICAgICAgICIxIiA9ICIjNTZjZmUxIiwgCiAgICAgICAgICAgICAgICIyIiA9ICIjNTk3OGQ0IiwKICAgICAgICAgICAgICAgIjMiID0gIiNiNTE3OWUiKSkrCiAgdGhlbWVfbWluaW1hbCgpCgojIEV4aWJhIG8gZ3LDoWZpY28KcHJpbnQocGNhX3Bsb3RfY29uZGl0aW9uKQpwcmludChwY2FfcGxvdF9kYXkpCnByaW50KHBjYV9wbG90X2Rvc2UpCnByaW50KHBjYV9wbG90X3ZhYykKCmdnc2F2ZShwY2FfcGxvdF9jb25kaXRpb24sIGZpbGVuYW1lID0gcGFzdGUwKGZpbGVuYW1lLCAiQ09ORElUSU9OX1BDQV9JbW11bmVfR09fR1NFQV9ub3QtYW5uLnBuZyIpLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA4KQpnZ3NhdmUocGNhX3Bsb3RfdmFjLCBmaWxlbmFtZSA9IHBhc3RlMChmaWxlbmFtZSwgIl9WQUNDSU5FX1BDQV9JbW11bmVfR09fR1NFQV9ub3QtYW5uLnBuZyIpLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA4KQpnZ3NhdmUocGNhX3Bsb3RfZGF5LCBmaWxlbmFtZSA9IHBhc3RlMChmaWxlbmFtZSwgIl9EQVlfUENBX0ltbXVuZV9HT19HU0VBX25vdC1hbm4ucG5nIiksIHdpZHRoID0gMTAsIGhlaWdodCA9IDgpCmdnc2F2ZShwY2FfcGxvdF9kb3NlLCBmaWxlbmFtZSA9IHBhc3RlMChmaWxlbmFtZSwgIl9ET1NFX1BDQV9JbW11bmVfR09fR1NFQV9ub3QtYW5uLnBuZyIpLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA4KQoKYGBgCgoKYGBge3J9CiMjIyMjIyMjIyMjIyMjIyBLTk4gY2xhc3NpZmljYXRpb24KCiNEZXRlcm1pbmFyIG8gbsO6bWVybyBkZSBjbHVzdGVycyBwYXJhIEtOTgpwY2Ffc2NvcmVzIDwtIGRhdGEuZnJhbWUocGNhX3JlcyR4WywgMToyXSkKZnZpel9uYmNsdXN0KHBjYV9zY29yZXMsICAKICAgICAgICAgICAgICAgICAgICAgRlVOY2x1c3RlciA9IGttZWFucywKICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gIndzcyIpCgpzZXQuc2VlZCgxMjMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFNldCBzZWVkIGZvciByYW5kb21pemF0aW9uCmttZWFuc19jbHVzdCA8LSBrbWVhbnMocGNhX3Njb3JlcywgICAgICAgICMgUGVyZm9ybSBrLW1lYW5zIGNsdXN0ZXJpbmcKICAgICAgICAgICAgICAgICAgICAgICAgY2VudGVycyA9IDMpICMgRGVmaW5pciBudW1lcm8gZGUgY2x1c3RlcnMKCiNWaXN1YWxpemFyIGNsdXN0ZXJzCmdncDIgPC0gZnZpel9wY2FfaW5kKHBjYV9yZXMsCiAgICAgICAgICAgICAgICAgICBoYWJpbGxhZ2UgPSBrbWVhbnNfY2x1c3QkY2x1c3RlciwKICAgICAgICAgICAgICAgICAgIHJlcGVsID0gVFJVRSwKICAgICAgICAgICAgICAgICAgIGFkZEVsbGlwc2VzID0gVFJVRSwKICAgICAgICAgICAgICAgICAgIGVsbGlwc2UudHlwZSA9ICJ0IiwKICAgICAgICAgICAgICAgICAgIGxhYmVsID0gIm5vbmUiLAogICAgICAgICAgICAgICAgICAgbGFiZWxzaXplID0gMCkgKwogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGxhYmVsID0gIiIpKSkgKwogIGdndGl0bGUocGFzdGUwKGZpbGVuYW1lLCAgIl9LTk5fQ2x1c3RlcmVkLnBuZyIpKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKQoKcHJpbnQoZ2dwMikKCmdnc2F2ZShnZ3AyLCBmaWxlID0gcGFzdGUwKGZpbGVuYW1lLCAiX0tOTl9DbHVzdGVyZWQucG5nIiksIHdpZHRoID0gNSwgaGVpZ2h0ID0gNCkKCgojIENsdXN0ZXJpemFyIHBvciBncnVwbwoKI1ZhY2NpbmUKcGNhX2dyb3VwX3ZhYyA8LSBmdml6X3BjYV9pbmQocGNhX3JlcywKICAgICAgICAgICAgICAgICAgIGhhYmlsbGFnZSA9IGFubl92YWNjaW5lc19wY2FfbWF0cml4X3JlYWR5JHZhY2NpbmUsCiAgICAgICAgICAgICAgICAgICByZXBlbCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICBhZGRFbGxpcHNlcyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICBlbGxpcHNlLnR5cGUgPSAidCIsCiAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICJub25lIiwKICAgICAgICAgICAgICAgICAgIGxhYmVsc2l6ZSA9IDApICsKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChsYWJlbCA9ICIiKSkpICsKICBnZ3RpdGxlKHBhc3RlMChmaWxlbmFtZSwgICJfVmFjX0tOTl9DbHVzdGVyZWQucG5nIikpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpCgojRG9zZQpwY2FfZ3JvdXBfZG9zZSA8LSBmdml6X3BjYV9pbmQocGNhX3JlcywKICAgICAgICAgICAgICAgICAgIGhhYmlsbGFnZSA9IGFubl92YWNjaW5lc19wY2FfbWF0cml4X3JlYWR5JGRvc2UsCiAgICAgICAgICAgICAgICAgICByZXBlbCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICBhZGRFbGxpcHNlcyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICBlbGxpcHNlLnR5cGUgPSAidCIsCiAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICJub25lIiwKICAgICAgICAgICAgICAgICAgIGxhYmVsc2l6ZSA9IDApICsKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChsYWJlbCA9ICIiKSkpICsKICBnZ3RpdGxlKHBhc3RlMChmaWxlbmFtZSwgICJfRG9zZV9LTk5fQ2x1c3RlcmVkLnBuZyIpKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKQoKI0RheQpwY2FfZ3JvdXBfZGF5IDwtIGZ2aXpfcGNhX2luZChwY2FfcmVzLAogICAgICAgICAgICAgICAgICAgaGFiaWxsYWdlID0gYW5uX3ZhY2NpbmVzX3BjYV9tYXRyaXhfcmVhZHkkZGF5LAogICAgICAgICAgICAgICAgICAgcmVwZWwgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgYWRkRWxsaXBzZXMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgZWxsaXBzZS50eXBlID0gInQiLAogICAgICAgICAgICAgICAgICAgbGFiZWwgPSAibm9uZSIsCiAgICAgICAgICAgICAgICAgICBsYWJlbHNpemUgPSAwKSArCiAgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QobGFiZWwgPSAiIikpKSArCiAgZ2d0aXRsZShwYXN0ZTAoZmlsZW5hbWUsICAiX0RheV9LTk5fQ2x1c3RlcmVkLnBuZyIpKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKQoKCiNTYWx2YXIKZ2dzYXZlKHBjYV9ncm91cF9kYXksIGZpbGUgPSBwYXN0ZTAoZmlsZW5hbWUsICJfRGF5X0NsdXN0ZXJlZC5wbmciKSwgd2lkdGggPSA1LCBoZWlnaHQgPSA0KQpnZ3NhdmUocGNhX2dyb3VwX2Rvc2UsIGZpbGUgPSBwYXN0ZTAoZmlsZW5hbWUsICJfRG9zZV9DbHVzdGVyZWQucG5nIiksIHdpZHRoID0gNSwgaGVpZ2h0ID0gNCkKZ2dzYXZlKHBjYV9ncm91cF92YWMsIGZpbGUgPSBwYXN0ZTAoZmlsZW5hbWUsICJfVmFjX0NsdXN0ZXJlZC5wbmciKSwgd2lkdGggPSA1LCBoZWlnaHQgPSA0KQpgYGAKCgpgYGB7cn0KI0JpcGxvdApiaXBsb3QgPSBmdml6X3BjYV9iaXBsb3QocGNhX3JlcywgICAgICAgICAgICAgICMgVmlzdWFsaXplIGNsdXN0ZXJzIGluIGJpcGxvdAogICAgICAgICAgICAgICAgICAgICAgY29sLnZhciA9ICJibGFjayIsCiAgICAgICAgICAgICAgICAgICAgICBhbHBoYS52YXIgPSAwLjUsCiAgICAgICAgICAgICAgICAgICAgICBoYWJpbGxhZ2UgPSBrbWVhbnNfY2x1c3QkY2x1c3RlciwKICAgICAgICAgICAgICAgICAgICAgIHJlcGVsID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgIGFkZEVsbGlwc2VzID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgIGVsbGlwc2UudHlwZSA9ICJjb252ZXgiLAogICAgICAgICAgICAgICAgICAgICAgbGFiZWxzaXplID0gMywKICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gInZhciIsCiAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gIlNldDEiKQoKCmdnc2F2ZShiaXBsb3QsIGZpbGUgPSBwYXN0ZTAoZmlsZW5hbWUsICJfQklQTE9UX0tOTl9DbHVzdGVyZWQucG5nIiksIHdpZHRoID0gMTAsIGhlaWdodCA9IDgpCmBgYAoKCmBgYHtyfQojIyMjIyMjI0NvcnJlbGF0aW9uIHBsb3QKY29ycl9tYXRyaXggPSBjb3IobWF0cml4X2RhdGFfcGNhX3JlYWR5KSAKCiNQbG90CmNvcnJwbG90ID0gZ2djb3JycGxvdChjb3JyX21hdHJpeCwgaGMub3JkZXIgPSBUUlVFKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHNpemUgPSA1KSwgCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDUpKQojU2FsdmFyCmdnc2F2ZShjb3JycGxvdCwgZmlsZSA9IHBhc3RlMChmaWxlbmFtZSwgIl9jb3JycGxvdC5wbmciKSwgCiAgICAgICB3aWR0aCA9IDQsICNHcmFuZGUgMjAsIHBlcXVlbm8gMTAKICAgICAgIGhlaWdodD0gNCkgI0dyYW5kZSAyMCwgcGVxdWVubyAxMApwcmludChjb3JycGxvdCkKZGF0YS5wY2EgPC0gcHJpbmNvbXAoY29ycl9tYXRyaXgpICNQQ0EKc3VtbWFyeShkYXRhLnBjYSkgI1JldG9ybmFyIFBDcwoKCiMjIyMjIyMjI1NjcmVlIHBsb3QKZGF0YS5wY2EgPSBwcmluY29tcChjb3JyX21hdHJpeCkgI1BDQQpzdW1tYXJ5KGRhdGEucGNhKSAjUmV0b3JuYXIgUENzCgojIyMjIyMjIyNTY3JlZSBwbG90CnNjcmVlX3Bsb3QgPSBmdml6X2VpZyhkYXRhLnBjYSwgCiAgICAgICAgICAgICAgICAgICAgICBhZGRsYWJlbHMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgeWxpbSA9IGMoMCwgNzApKSArCiAgZ2VvbV9jb2woY29sb3IgPSAiIzAwQUZCQiIsIGZpbGwgPSAiIzAwQUZCQiIpICsKICB0aGVtZV9jbGFzc2ljKCkKCiNTYWx2YXIKZ2dzYXZlKHNjcmVlX3Bsb3QsIGZpbGUgPSBwYXN0ZTAoZmlsZW5hbWUsICJfR1NFQV9zY3JlZXBsb3QucG5nIiksIHdpZHRoID0gMTAsIGhlaWdodCA9IDMpIApwcmludChzY3JlZV9wbG90KQoKCiNTY3JlZSBwbG90CmxvYWRpbmdzID0gZGF0YS5mcmFtZShkYXRhLnBjYSRsb2FkaW5nc1ssIDE6M10pCmxvYWRpbmdzJEdlbmVzID0gcm93bmFtZXMobG9hZGluZ3MpCmxvYWRpbmdzXzEgPSBhcnJhbmdlKGxvYWRpbmdzLCBkZXNjKENvbXAuMSkpCmxvYWRpbmdzXzIgPSBhcnJhbmdlKGxvYWRpbmdzLCBkZXNjKENvbXAuMikpCmxvYWRpbmdzXzMgPSBhcnJhbmdlKGxvYWRpbmdzLCBkZXNjKENvbXAuMykpCgojUGxvdApsb2FkaW5nc18xX3Bsb3QgPSBnZ3Bsb3QobG9hZGluZ3NfMSwgYWVzKHggPSByZW9yZGVyKEdlbmVzLCAtQ29tcC4xKSwgeT1Db21wLjEsIGZpbGwgPSBDb21wLjEpKSArIAogIGdndGl0bGUocGFzdGUwKCJDb21wMS1Db21wMiBHZW5lcyIsIGZpbGVuYW1lKSkgKyAKICB5bGFiKCJDb21wMSIpICsKICB4bGFiKCJHZW5lIHNldHMiKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsgCiAgdGhlbWVfbGlnaHQoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQodmp1c3QgPSAxLCBoanVzdCA9IDEsIGFuZ2xlID0gNDUsIHNpemUgPSA4KSwgCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDUpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1TCwgaGp1c3QgPSAwLjUpKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiKSAjY29yZXMKCnByaW50KGxvYWRpbmdzXzFfcGxvdCkKCgpsb2FkaW5nc18yX3Bsb3QgPSBnZ3Bsb3QobG9hZGluZ3NfMiwgYWVzKHggPSByZW9yZGVyKEdlbmVzLCAtQ29tcC4yKSwgeT1Db21wLjIsIGZpbGwgPSBDb21wLjIpKSArIAogIGdndGl0bGUocGFzdGUwKCJDb21wMi1Db21wMyBHZW5lc18iLCBmaWxlbmFtZSkpICsgCiAgeWxhYigiQ29tcDIiKSArCiAgeGxhYigiR2VuZSBzZXRzIikgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArIAogIHRoZW1lX2xpZ2h0KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMSwgaGp1c3QgPSAxLCBhbmdsZSA9IDQ1LCBzaXplID0gOCksIAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA1KSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNUwsIGhqdXN0ID0gMC41KSkgKyAKICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIikgI2NvcmVzCgpwcmludChsb2FkaW5nc18yX3Bsb3QpCgoKI1NhbHZhcgpnZ3NhdmUobG9hZGluZ3NfMV9wbG90LCAKICAgICAgIGZpbGUgPSBwYXN0ZTAoZmlsZW5hbWUsICJfR1NFQV9nZW5lc2NvbXAxLTIucG5nIiksIAogICAgICAgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNSkKCiNTYWx2YXIKZ2dzYXZlKGxvYWRpbmdzXzJfcGxvdCwgCiAgICAgICBmaWxlID0gcGFzdGUwKGZpbGVuYW1lLCAiX0dTRUFfZ2VuZXNjb21wMi0zLnBuZyIpLCAKICAgICAgIHdpZHRoID0gMTAsIGhlaWdodCA9IDUpCgoKIyBHcmFwaCBvZiB0aGUgdmFyaWFibGVzCmZ2aXpfcGNhX3Zhcl9nZW5lcyA9IGZ2aXpfcGNhX3ZhcihkYXRhLnBjYSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuaW5kID0gImNvczIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JhZGllbnQuY29scyA9IGMoIiMwMEFGQkIiLCAiI0U3QjgwMCIsICIjRkM0RTA3IikpCmZ2aXpfcGNhX3Zhcl9nZW5lcwoKZ2dzYXZlKGZ2aXpfcGNhX3Zhcl9nZW5lcywgZmlsZSA9IHBhc3RlMChmaWxlbmFtZSwgIl9mdml6X3BjYV92YXJfR1NFQS5wbmciKSwgd2lkdGggPSAxMCkKCmNvczIuMSA9IGZ2aXpfY29zMihkYXRhLnBjYSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAxOjIpCmNvczIuMiA9IGZ2aXpfY29zMihkYXRhLnBjYSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAyOjMpCgpnZ3NhdmUoY29zMi4xLCBmaWxlID0gcGFzdGUwKGZpbGVuYW1lLCAiX2NvczJfR1NFQV8xLnBuZyIpLCB3aWR0aCA9IDEwKQpnZ3NhdmUoY29zMi4yLCBmaWxlID0gcGFzdGUwKGZpbGVuYW1lLCAiX2NvczJfR1NFQV8yLnBuZyIpLCB3aWR0aCA9IDEwKQoKYGBgCgoKIyMjIyBCeSBnZW5lcwoKClByb2Nlc3NhciBkYWRvcwpgYGB7cn0KIyBJbW11bmVfR09fZ2VuZXJhbF9pbm5hdGUKIyBJbW11bmVfR09fYWRhcHRpdmUKCiNJTlBVVApkYXRhX2dlbmVzID0gc3Nnc2VhX3Jlc3VsdHNfdW5pZmllZApmaWxlbmFtZSA9ICJzc2dzZWFfcmVzdWx0c191bmlmaWVkIgpgYGAKClBDQQoKYGBge3J9CiNDb252ZXJ0ZXIgZGUgbG9uZyBwYXJhIHdpZGUKbWF0cml4X2dlbmVzID0gZGF0YV9nZW5lcyAlPiUgCiAgc2VsZWN0KHN0dWR5LCBnZW5lcywgbDJmYykgJT4lICAKICBkY2FzdChgc3R1ZHlgIH4gYGdlbmVzYCwgCiAgICAgICAgdmFsdWUudmFyID0gImwyZmMiLCAKICAgICAgICBmdW4uYWdncmVnYXRlID0gbWVhbikgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgY29sdW1uX3RvX3Jvd25hbWVzKHZhciA9ICJzdHVkeSIpICU+JSAKICByZXBsYWNlKGlzLm5hKC4pLCAwKQoKbWF0cml4X2RhdGFfcGNhID0gbWF0cml4X2dlbmVzICU+JSAKICByb3duYW1lc190b19jb2x1bW4odmFyID0gIkNvbmRpdGlvbiIpCgptYXRyaXhfZGF0YV9wY2FfcmVhZHkgPSBtYXRyaXhfZGF0YV9wY2EgJT4lIAogIGNvbHVtbl90b19yb3duYW1lcyh2YXIgPSAiQ29uZGl0aW9uIikKCmFubl92YWNjaW5lc19wY2FfbWF0cml4ID0gYW5uX3ZhY2NpbmVzX3BjYSAlPiUgCiAgbWVyZ2UobWF0cml4X2RhdGFfcGNhLCAKICAgICAgICBieS54ID0gIkNvbmRpdGlvbiIsIAogICAgICAgIGFsbC54ID0gRiwgCiAgICAgICAgYWxsLnkgPSBGKSAlPiUgCiAgc2VsZWN0KENvbmRpdGlvbjpFZmZpY2FjeSkKCiMgVmVyaWZpcXVlIHF1YWlzIGNvbHVuYXMgdMOqbSB2YXJpw6JuY2lhIG11aXRvIGJhaXhhCm5lYXJaZXJvVmFyQ29scyA8LSBuZWFyWmVyb1ZhcihtYXRyaXhfZGF0YV9wY2FfcmVhZHksIHNhdmVNZXRyaWNzID0gVFJVRSkKbWF0cml4X2RhdGFfcGNhX3JlYWR5IDwtIG1hdHJpeF9kYXRhX3BjYV9yZWFkeVssICFuZWFyWmVyb1ZhckNvbHMkbnp2XQpwY2FfcmVzIDwtIHByY29tcChtYXRyaXhfZGF0YV9wY2FfcmVhZHksIHNjYWxlLiA9IFRSVUUpCgojIENyaWUgbyBncsOhZmljbyBkZSBQQ0EKcGNhX3Bsb3RfYW5uID0gYXV0b3Bsb3QocGNhX3JlcywgCiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGFubl92YWNjaW5lc19wY2FfbWF0cml4LCAKICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAnVmFjY2luZScsIAogICAgICAgICAgICAgICAgICAgIGxhYmVsID0gMSkgKyAjMTogZGlzcGxheSwgMDogaGlkZQogIGxhYnModGl0bGU9ZmlsZW5hbWUpICsKICB0aGVtZV9jbGFzc2ljKCkKICAjIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKEJCSUJQID0gIiNibGFjayIsIAogICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWkYyMDAxID0gImJsYWNrIiwKICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJOVCA9ICIjNTZjZmUxIiwKICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENoQWQgPSAiIzgwZmZkYiIgLAogICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNoQWQtQk5UIiA9ICIjNzJlZmRkIikpIAoKcGNhX3Bsb3Rfbm90X2FubiA9IGF1dG9wbG90KHBjYV9yZXMsIAogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBhbm5fdmFjY2luZXNfcGNhX21hdHJpeCwgCiAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gJ1ZhY2NpbmUnLCAKICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IDApICsgIzE6IGRpc3BsYXksIDA6IGhpZGUKICBsYWJzKHRpdGxlPWZpbGVuYW1lKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICBzdGF0X2VsbGlwc2UodHlwZSA9ICJ0IikKCiNTYWx2YXIKZ2dzYXZlKHBjYV9wbG90X25vdF9hbm4sIGZpbGVuYW1lID0gcGFzdGUwKGZpbGVuYW1lLCAiX1BDQV9ub3QtYW5uLnBuZyIpLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA4KQpnZ3NhdmUocGNhX3Bsb3RfYW5uLCBmaWxlbmFtZSA9IHBhc3RlMChmaWxlbmFtZSwgIl9QQ0FfYW5uLnBuZyIpLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA4KQoKIyBFeGliYSBvIGdyw6FmaWNvCnByaW50KHBjYV9wbG90X2FubikKcHJpbnQocGNhX3Bsb3Rfbm90X2FubikKCiMjIyMjIyMjIyMjIyMjIyBLTk4gY2xhc3NpZmljYXRpb24KCiNEZXRlcm1pbmFyIG8gbsO6bWVybyBkZSBjbHVzdGVycyBwYXJhIEtOTgpwY2Ffc2NvcmVzIDwtIGRhdGEuZnJhbWUocGNhX3JlcyR4WywgMToyXSkKZ2dwMSA8LSBmdml6X25iY2x1c3QocGNhX3Njb3JlcywgIAogICAgICAgICAgICAgICAgICAgICBGVU5jbHVzdGVyID0ga21lYW5zLAogICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSAid3NzIikKCmdncDEgCgpzZXQuc2VlZCgxMjMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFNldCBzZWVkIGZvciByYW5kb21pemF0aW9uCmttZWFuc19jbHVzdCA8LSBrbWVhbnMocGNhX3Njb3JlcywgICAgICAgICMgUGVyZm9ybSBrLW1lYW5zIGNsdXN0ZXJpbmcKICAgICAgICAgICAgICAgICAgICAgICAgY2VudGVycyA9IDQpICMgRGVmaW5pciBudW1lcm8gZGUgY2x1c3RlcnMKCiNWaXN1YWxpemFyIGNsdXN0ZXJzCmdncDIgPC0gZnZpel9wY2FfaW5kKHBjYV9yZXMsCiAgICAgICAgICAgICAgICAgICBoYWJpbGxhZ2UgPSBrbWVhbnNfY2x1c3QkY2x1c3RlciwKICAgICAgICAgICAgICAgICAgIHJlcGVsID0gVFJVRSwKICAgICAgICAgICAgICAgICAgIGFkZEVsbGlwc2VzID0gVFJVRSwKICAgICAgICAgICAgICAgICAgIGVsbGlwc2UudHlwZSA9ICJjb252ZXgiLAogICAgICAgICAgICAgICAgICAgbGFiZWxzaXplID0gMikgKwogICAgIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGxhYmVsID0gIiIpKSkgKwogIGdndGl0bGUocGFzdGUwKGZpbGVuYW1lLCAgIktOTl9DbHVzdGVyZWQucG5nIikpCgpwcmludChnZ3AyKQpnZ3NhdmUoZ2dwMiwgZmlsZSA9IHBhc3RlMChmaWxlbmFtZSwgIktOTl9DbHVzdGVyZWQucG5nIiksIHdpZHRoID0gNSwgaGVpZ2h0ID0gNCkKCgpgYGAKCgpgYGB7cn0KIyMjIyMjIyNDb3JyZWxhdGlvbiBwbG90CiNNYXRyaXoKY29ycl9tYXRyaXggPSBjb3IobWF0cml4X2RhdGFfcGNhX3JlYWR5KSAKCiNQbG90CmNvcnJwbG90ID0gZ2djb3JycGxvdChjb3JyX21hdHJpeCwgaGMub3JkZXIgPSBUUlVFKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHNpemUgPSA1KSwgCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDUpKQojU2FsdmFyCmdnc2F2ZShjb3JycGxvdCwgZmlsZSA9IHBhc3RlMChmaWxlbmFtZSwgIl9jb3JycGxvdC5wbmciKSwgCiAgICAgICB3aWR0aCA9IDIwLCAjR3JhbmRlIDIwLCBwZXF1ZW5vIDEwCiAgICAgICBoZWlnaHQ9IDIwKSAjR3JhbmRlIDIwLCBwZXF1ZW5vIDEwCnByaW50KGNvcnJwbG90KQoKIyMjIyMjIyMjU2NyZWUgcGxvdApkYXRhLnBjYSA9IHByaW5jb21wKGNvcnJfbWF0cml4KSAjUENBCnN1bW1hcnkoZGF0YS5wY2EpICNSZXRvcm5hciBQQ3MKCiMjIyMjIyMjI1NjcmVlIHBsb3QKc2NyZWVfcGxvdCA9IGZ2aXpfZWlnKGRhdGEucGNhLCAKICAgICAgICAgICAgICAgICAgICAgIGFkZGxhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICB5bGltID0gYygwLCA3MCkpICsKICBnZW9tX2NvbChjb2xvciA9ICIjMDBBRkJCIiwgZmlsbCA9ICIjMDBBRkJCIikgKwogIHRoZW1lX2NsYXNzaWMoKQoKI1NhbHZhcgpnZ3NhdmUoc2NyZWVfcGxvdCwgZmlsZSA9IHBhc3RlMChmaWxlbmFtZSwgIl9zY3JlZXBsb3QucG5nIiksIHdpZHRoID0gMTAsIGhlaWdodCA9IDMpIApwcmludChzY3JlZV9wbG90KQoKI0NvbXAxLUNvbXAyCmxvYWRpbmdzID0gZGF0YS5mcmFtZShkYXRhLnBjYSRsb2FkaW5nc1ssIDE6M10pCmxvYWRpbmdzJEdlbmVzID0gcm93bmFtZXMobG9hZGluZ3MpCmxvYWRpbmdzXzEgPSBhcnJhbmdlKGxvYWRpbmdzLCBkZXNjKENvbXAuMSkpCmxvYWRpbmdzXzIgPSBhcnJhbmdlKGxvYWRpbmdzLCBkZXNjKENvbXAuMikpCmxvYWRpbmdzXzMgPSBhcnJhbmdlKGxvYWRpbmdzLCBkZXNjKENvbXAuMykpCgojUGxvdApsb2FkaW5nc18xX3Bsb3QgPSBnZ3Bsb3QobG9hZGluZ3NfMSwgYWVzKHggPSByZW9yZGVyKEdlbmVzLCAtQ29tcC4xKSwgeT1Db21wLjEsIGZpbGwgPSBDb21wLjEpKSArIAogIGdndGl0bGUocGFzdGUwKCJDb21wMS1Db21wMiBHZW5lcyIsIGZpbGVuYW1lKSkgKyAKICB5bGFiKCJDb21wMSIpICsKICB4bGFiKCJHZW5lcyIpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKyAKICB0aGVtZV9saWdodCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IDAuMSwgaGp1c3QgPSAxLCBhbmdsZSA9IDkwLCBzaXplID0gMyksIAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA1KSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNUwsIGhqdXN0ID0gMC41KSkgKyAKICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIikgI2NvcmVzCiAgCiNTYWx2YXIKZ2dzYXZlKGxvYWRpbmdzXzFfcGxvdCwgCiAgICAgICBmaWxlID0gcGFzdGUwKGZpbGVuYW1lLCAiX2dlbmVzY29tcDEtMi5wbmciKSwgCiAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSA1KQoKcHJpbnQobG9hZGluZ3NfMV9wbG90KQpgYGAKCgpgYGB7cn0KIyBHcmFwaCBvZiB0aGUgdmFyaWFibGVzCmZ2aXpfcGNhX3Zhcl9nZW5lcyA9IGZ2aXpfcGNhX3ZhcihkYXRhLnBjYSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuaW5kID0gImNvczIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JhZGllbnQuY29scyA9IGMoIiMwMEFGQkIiLCAiI0U3QjgwMCIsICIjRkM0RTA3IikpCgojU2FsdmFyCmdnc2F2ZShmdml6X3BjYV92YXJfZ2VuZXMsIGZpbGUgPSBwYXN0ZTAoZmlsZW5hbWUsICJfZnZpel9wY2FfdmFyX2dlbmVzLnBuZyIpLCB3aWR0aCA9IDEwKQoKIyMjIyMjIyMjIENPUzIKY29zMiA9IGZ2aXpfY29zMihkYXRhLnBjYSwgCiAgICAgICAgICAgICAgICAgY2hvaWNlID0gInZhciIsIAogICAgICAgICAgICAgICAgIGF4ZXMgPSAxOjIpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NDUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAzKSkgKwogIHRoZW1lX2xpZ2h0KCkKCiNTYWx2YXIKZ2dzYXZlKGNvczIsIGZpbGUgPSBwYXN0ZTAoZmlsZW5hbWUsICJfY29zMi5wbmciKSwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNSkKCiNDb2xvcmlkbwpmdml6X3BjYV92YXIoZGF0YS5wY2EsIGNvbC52YXIgPSAiY29zMiIsCiAgICAgICAgICAgIGdyYWRpZW50LmNvbHMgPSBjKCJibGFjayIsICJvcmFuZ2UiLCAiZ3JlZW4iKSwKICAgICAgICAgICAgcmVwZWwgPSBUUlVFKQoKI1ByaW50CnByaW50KGZ2aXpfcGNhX3Zhcl9nZW5lcykKcHJpbnQoY29zMikKYGBgCgoKIyMgQ2VsbE1hcmtlcgoKYGBge3J9CgpgYGAKCgoKCgoKCgojR1NFQQoKIyMgTWFudWFsCmBgYHtyfQojIyMjIyMjIyMgSU5QVVQgQVFVSSAjIyMjIyMjIyMgCiMgYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWQgPSBhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZF8yN18xMV8yMyAlPiUKIyAgIG11dGF0ZShjb25kaXRpb24gPSBjYXNlX3doZW4oY29uZGl0aW9uID09ICJILUJOVC1JIChEMSkiIH4gIkJOVC1JIChEMSkiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25kaXRpb24gPT0gIkgtQk5ULUkgKEQzKSIgfiAiQk5ULUkgKEQzKSIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbiA9PSAiSC1CTlQtSSAoRDQpIiB+ICJCTlQtSSAoRDQpIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uID09ICJILUktSSAoRDIpIiB+ICJJLUkgKEQyKSIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbiA9PSAiSS1CTlQtSSAoRDIpIiB+ICJJLUJOVC1JIChEMikiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25kaXRpb24gPT0gIkktQk5ULUkgKEQ1KSIgfiAiSS1CTlQtSSAoRDUpIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uID09ICJILUJOVC1JIChEMTAsIG1pbGQpIiB+ICJCTlQtSSAoRDEwLCBtaWxkKSIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbiA9PSAiSC1CTlQtSSAoRDEwLCBzZXZlcmUpIiB+ICJCTlQtSSAoRDEwLCBzZXZlcmUpIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uID09ICJILUJOVC1JIChEMjYsIG1pbGQpIiB+ICJCTlQtSSAoRDI2LCBtaWxkKSIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbiA9PSAiSC1CTlQtSSAoRDI2LCBzZXZlcmUpIiB+ICJCTlQtSSAoRDI2LCBzZXZlcmUpIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uID09ICJILUkgKEQxMCwgbW9kZXJhdGUpIiB+ICJJIChEMTAsIG1vZGVyYXRlKSIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbiA9PSAiSC1JIChEMTAsIHNldmVyZSkiIH4gIkkgKEQxMCwgc2V2ZXJlKSIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbiA9PSAiSC1JIChEMjYsIG1vZGVyYXRlKSIgfiAiSSAoRDI2LCBtb2RlcmF0ZSkiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25kaXRpb24gPT0gIkgtSSAoRDI2LCBzZXZlcmUpIiB+ICJJIChEMjYsIHNldmVyZSkiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25kaXRpb24gPT0gIkgtSSAoRDUxLCBtb2RlcmF0ZSkiIH4gIkkgKEQ1MSwgbW9kZXJhdGUpIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uID09ICJILUkgKEQ1MSwgc2V2ZXJlKSIgfiAiSSAoRDUxLCBzZXZlcmUpIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IGNvbmRpdGlvbikpCiMgCiMgd3JpdGUuY3N2KGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkXzI3XzExXzIzLCBmaWxlID0iYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWRfMjlfMTFfMjMuY3N2IikKCmFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkCgojR1NFMTk5NzUwCiMgZGVncyA8LSBmaWx0ZXIoYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWQsIGNvbmRpdGlvbiA9PSAiQk5UIChWMSwgRDYpIikgI07Do28gZW5yaXF1ZWNpZG8KIyBkZWdzIDwtIGZpbHRlcihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgY29uZGl0aW9uID09ICJCTlQgKFYyLCBEMSkiKSAjRW5yaXF1ZWNpZG8KIyBkZWdzIDwtIGZpbHRlcihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgY29uZGl0aW9uID09ICJCTlQgKFYzLCBEMSkiKSAjRW5yaXF1ZWNpZG8KIyBkZWdzIDwtIGZpbHRlcihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgY29uZGl0aW9uID09ICJCTlQtTU8gKFYzLCBEMSkiKSAjRW5yaXF1ZWNpZG8KIyBkZWdzIDwtIGZpbHRlcihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgY29uZGl0aW9uID09ICJDaEFkIChWMSwgRDYpIikgI0VucmlxdWVjaWRvCiMgZGVncyA8LSBmaWx0ZXIoYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWQsIGNvbmRpdGlvbiA9PSAiQ2hBZCAoVjIsIEQxKSIpICNFbnJpcXVlY2lkbwojIGRlZ3MgPC0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkNoQWQtQk5UIChWMywgRDEpIikgI07Do28gZW5yaXF1ZWNpZG8KCiNHU0UyMDE1MzMKIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkNoQWQgKFYxLCBEMykiKSAjRW5yaXF1ZWNpZG8KIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkNoQWQgKFYxLCBENykiKSAjRW5yaXF1ZWNpZG8KIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkNoQWQgKFYyLCBEMykiKSAjTsOjbyBlbnJpcXVlY2lkbwojIGRlZ3MgPSBmaWx0ZXIoYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWQsIGNvbmRpdGlvbiA9PSAiQ2hBZCAoVjIsIEQ3KSIpICNFbnJpcXVlY2lkbwojIGRlZ3MgPSBmaWx0ZXIoYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWQsIGNvbmRpdGlvbiA9PSAiQ2hBZC1CTlQgKFYyLCBEMykiKSAjRW5yaXF1ZWNpZG8KIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkNoQWQtQk5UIChWMiwgRDcpIikgI0VucmlxdWVjaWRvCgojR1NFMjA2MDIzCiMgZGVncyA9IGZpbHRlcihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgY29uZGl0aW9uID09ICJCQklCUCAoVjMsIEQwNykiKSAjRW5yaXF1ZWNpZG8KIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkJCSUJQIChWMywgRDE0KSIpICNOw6NvIGVucmlxdWVjaWRvCiMgZGVncyA9IGZpbHRlcihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgY29uZGl0aW9uID09ICJCQklCUCAoVjMsIEQyOCkiKSAjRW5yaXF1ZWNpZG8KIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIlpGMjAwMSAoVjMsIEQwNykiKSAjRW5yaXF1ZWNpZG8KIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIlpGMjAwMSAoVjMsIEQxNCkiKSAjRW5yaXF1ZWNpZG8KIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIlpGMjAwMSAoVjMsIEQyOCkiKSAjRW5yaXF1ZWNpZG8KCiNHU0UyMDE1MzAKIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkJOVC1JIChEMSkiKQojIGRlZ3MgPSBmaWx0ZXIoYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWQsIGNvbmRpdGlvbiA9PSAiQk5ULUkgKEQzKSIpCiMgZGVncyA9IGZpbHRlcihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgY29uZGl0aW9uID09ICJCTlQtSSAoRDQpIikKIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkktSSAoRDIpIikKIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkktQk5ULUkgKEQyKSIpCiMgZGVncyA9IGZpbHRlcihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgY29uZGl0aW9uID09ICJJLUJOVC1JIChENSkiKQojIGRlZ3MgPSBmaWx0ZXIoYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWQsIGNvbmRpdGlvbiA9PSAiSS1JIChEMSkiKQojIGRlZ3MgPSBmaWx0ZXIoYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWQsIGNvbmRpdGlvbiA9PSAiSS1JIChEMykiKQojIGRlZ3MgPSBmaWx0ZXIoYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWQsIGNvbmRpdGlvbiA9PSAiSS1JIChENSkiKQoKCiNHU0UxODkwMzkKIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkJOVC1JLUJOVCAoRDUxLCBtaWxkKSIpCiMgZGVncyA9IGZpbHRlcihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgY29uZGl0aW9uID09ICJCTlQtSS1CTlQgKEQ1MSwgc2V2ZXJlKSIpCiMgZGVncyA9IGZpbHRlcihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgY29uZGl0aW9uID09ICJCTlQtSSAoRDEwLCBtaWxkKSIpCiMgZGVncyA9IGZpbHRlcihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgY29uZGl0aW9uID09ICJCTlQtSSAoRDEwLCBzZXZlcmUpIikKIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkJOVC1JIChEMjYsIG1pbGQpIikKIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkJOVC1JIChEMjYsIHNldmVyZSkiKQojIGRlZ3MgPSBmaWx0ZXIoYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWQsIGNvbmRpdGlvbiA9PSAiSSAoRDEwLCBtb2RlcmF0ZSkiKQojIGRlZ3MgPSBmaWx0ZXIoYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWQsIGNvbmRpdGlvbiA9PSAiSSAoRDEwLCBzZXZlcmUpIikKIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkkgKEQyNiwgbW9kZXJhdGUpIikKIyBkZWdzID0gZmlsdGVyKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBjb25kaXRpb24gPT0gIkkgKEQyNiwgc2V2ZXJlKSIpCiMgZGVncyA9IGZpbHRlcihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgY29uZGl0aW9uID09ICJJIChENTEsIG1vZGVyYXRlKSIpCiMgZGVncyA9IGZpbHRlcihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZCwgY29uZGl0aW9uID09ICJJIChENTEsIHNldmVyZSkiKQoKYGBgCgpgYGB7cn0KI0RlZmluaXIgbm9tZSBwYXJhIGFycXVpdm9zIGdlcmFkb3MKZmlsZV9uYW1lID0gZGVncyAlPiUgCiAgc2VsZWN0KGNvbmRpdGlvbikgJT4lIAogIGRpc3RpbmN0KCkgJT4lIAogIGFzLmNoYXJhY3RlcigpCgojIyMjIyMjIyMgREVHcyBwYXJhIE9SQSAjIyMjIyMjIyMgCmdlbmVfbGlzdF9vcmEgPC0gZGVncyRnZW5lcwojIyMjIyMjIyMgREVHcyBwYXJhIEdTRUEgIyMjIyMjIyMjIApkZWdzX2dlbmVfbGlzdF9sZjJjIDwtIGRlZ3MkbG9nMmZvbGRfY2hhbmdlCm5hbWVzKGRlZ3NfZ2VuZV9saXN0X2xmMmMpIDwtIGRlZ3MkZ2VuZXMKZGVnc19nZW5lX2xpc3RfbGYyYzwtbmEub21pdChkZWdzX2dlbmVfbGlzdF9sZjJjKQpkZWdzX2dlbmVfbGlzdF9sZjJjID0gc29ydChkZWdzX2dlbmVfbGlzdF9sZjJjLCBkZWNyZWFzaW5nID0gVFJVRSkKCiMjIyMjIyMjIyMjIyBJTU1VTkUgR08KSW1tdW5lX0dPX1QyRyA9IEltbXVuZUdPX0Fubm90YXRlZF9HZW5lc19OZXN0ZWRfSW50ZXJlc3RpbmcgJT4lIAogIHNlbGVjdChnZW5lX3NldF9zaG9ydCwgZ2VuZXMpCgppbW11bmVfR09fZ3NlYSA8LSBHU0VBKGRlZ3NfZ2VuZV9saXN0X2xmMmMsIAogICAgICAgICAgICAgICAgICAgICAgIFRFUk0yR0VORSA9IEltbXVuZV9HT19UMkcsIAogICAgICAgICAgICAgICAgICAgICAgIG1pbkdTU2l6ZSA9IDIsCiAgICAgICAgICAgICAgICAgICAgICAgbWF4R1NTaXplID0gMTAwMCwKICAgICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjI1LAogICAgICAgICAgICAgICAgICAgICAgIHBBZGp1c3RNZXRob2QgPSAiQkgiKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICBhcnJhbmdlKHF2YWx1ZSkgJT4lIAogIG11dGF0ZShjb25kaXRpb24gPSBmaWxlX25hbWUsCiAgICAgICAgIGdzZWFfZW5yaWNobWVudCA9ICJJbW11bmVHTyIpCgojU2FsdmFyIHRhYmVsYQp3cml0ZS5jc3YoaW1tdW5lX0dPX2dzZWEsIGZpbGUgPSBwYXN0ZShmaWxlX25hbWUsICJJbW11bmVHT19HU0VBLmNzdiIsIHNlcCA9ICJfIikpCgojIyMjIyMjIyMjIyBDRUxMIE1BUktFUgoKQ2VsbE1hcmtlcl9nZW5lcyA9IENlbGxNYXJrZXJfSW1tdW5lQ2VsbHMgJT4lIAogIHNlbGVjdChjZWxsX25hbWUsIG1hcmtlcikKCmNlbGxfdHlwZXNfZ3NlYV9pbW11bmUgPC0gR1NFQShkZWdzX2dlbmVfbGlzdF9sZjJjLCAKICAgICAgICAgICAgICAgICAgICAgICBURVJNMkdFTkUgPSBDZWxsTWFya2VyX2dlbmVzLCAKICAgICAgICAgICAgICAgICAgICAgICBtaW5HU1NpemUgPSAxLAogICAgICAgICAgICAgICAgICAgICAgIG1heEdTU2l6ZSA9IDEwMDAsCiAgICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4yNSwgCiAgICAgICAgICAgICAgICAgICAgICAgcEFkanVzdE1ldGhvZCA9ICJCSCIpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIGFycmFuZ2UocXZhbHVlKSAlPiUgCiAgbXV0YXRlKGNvbmRpdGlvbiA9IGZpbGVfbmFtZSwKICAgICAgICAgZ3NlYV9lbnJpY2htZW50ID0gIkNlbGxNYXJrZXIiKQoKI1NhbHZhciB0YWJlbGEKd3JpdGUuY3N2KGNlbGxfdHlwZXNfZ3NlYV9pbW11bmUsIGZpbGU9cGFzdGUoZmlsZV9uYW1lLCAiQ2VsbE1hcmtlcl9HU0VBLmNzdiIsIHNlcCA9ICJfIikpCgojIyMjIyMjIyMjIyBWQVggU0lHIERCCgp2YXhfc2lnX2dlbmVzID0gVkFYX0dlbmVzX0Fubm90YXRlZF9SQVcgJT4lIAogIHNlbGVjdChTVEFOREFSRF9OQU1FLCBHRU5FKQoKb3JhX2RlZ3NfdmF4IDwtIGVucmljaGVyKGdlbmVfbGlzdF9vcmEsIAogICAgICAgICAgICAgICAgICAgICAgIFRFUk0yR0VORSA9IHZheF9zaWdfZ2VuZXMsIAogICAgICAgICAgICAgICAgICAgICAgIG1pbkdTU2l6ZSA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgbWF4R1NTaXplID0gMTAwMCwKICAgICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjI1LCAKICAgICAgICAgICAgICAgICAgICAgICBwQWRqdXN0TWV0aG9kID0gIkJIIiklPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICBhcnJhbmdlKHF2YWx1ZSkgJT4lIAogIG11dGF0ZShjb25kaXRpb24gPSBmaWxlX25hbWUsCiAgICAgICAgIGdzZWFfZW5yaWNobWVudCA9ICJWQVhTaWciKQoKI1NhbHZhciAKd3JpdGUuY3N2KG9yYV9kZWdzX3ZheCwgZmlsZT1wYXN0ZShmaWxlX25hbWUsICJWQVhTaWdfT1JBLmNzdiIsIHNlcCA9ICJfIikpCgoKYGBgCgoKIyMgQXV0b21hdGl6YWRvCmBgYHtyfQojIEZ1bsOnw6NvIHBhcmEgcmVhbGl6YXIgYXMgYW7DoWxpc2VzIHBhcmEgY2FkYSB2YWxvciBkYSBjb2x1bmEgImNvbmRpdGlvbiIKR1NFQV9BTEwgPC0gZnVuY3Rpb24oZGYsIEltbXVuZV9HT19UMkcsIENlbGxNYXJrZXJfZ2VuZXMsIHZheF9zaWdfZ2VuZXMpIHsKICByZXN1bHRhZG9zIDwtIGxpc3QoKQoKICBjb25kaWNvZXMgPC0gZGYkY29uZGl0aW9uICU+JSB1bmlxdWUoKSAlPiUgYXMuY2hhcmFjdGVyKCkKCiAgZm9yIChjb25kaWNhbyBpbiBjb25kaWNvZXMpIHsKICAgICMgU2VsZWNpb25hciBERUdzIHBhcmEgYSBjb25kacOnw6NvIGF0dWFsCiAgICBnZW5lc19jb25kaWNhbyA8LSBkZiRnZW5lc1tkZiRjb25kaXRpb24gPT0gY29uZGljYW9dCiAgICBsb2dmb2xkY2hhbmdlX2NvbmRpY2FvIDwtIGRmJGxvZzJmb2xkX2NoYW5nZVtkZiRjb25kaXRpb24gPT0gY29uZGljYW9dCiAgICBuYW1lcyhsb2dmb2xkY2hhbmdlX2NvbmRpY2FvKSA8LSBnZW5lc19jb25kaWNhbwogICAgbG9nZm9sZGNoYW5nZV9jb25kaWNhbyA8LSBuYS5vbWl0KGxvZ2ZvbGRjaGFuZ2VfY29uZGljYW8pCiAgICBsb2dmb2xkY2hhbmdlX2NvbmRpY2FvIDwtIHNvcnQobG9nZm9sZGNoYW5nZV9jb25kaWNhbywgZGVjcmVhc2luZyA9IFRSVUUpCgogICAgICAgICMjIyMjIyMjIyMjIyBJTU1VTkUgR08KICAgIGltbXVuZV9HT19nc2VhIDwtIHRyeUNhdGNoKHsKICAgICAgR1NFQShsb2dmb2xkY2hhbmdlX2NvbmRpY2FvLAogICAgICAgICAgIFRFUk0yR0VORSA9IEltbXVuZV9HT19UMkcsCiAgICAgICAgICAgbWluR1NTaXplID0gMiwKICAgICAgICAgICBtYXhHU1NpemUgPSAxMDAwLAogICAgICAgICAgIHB2YWx1ZUN1dG9mZiA9IDAuMjUsCiAgICAgICAgICAgcEFkanVzdE1ldGhvZCA9ICJCSCIpICU+JQogICAgICAgIGFzLmRhdGEuZnJhbWUoKSAlPiUKICAgICAgICBhcnJhbmdlKHF2YWx1ZSkgJT4lCiAgICAgICAgbXV0YXRlKGNvbmRpdGlvbiA9IGNvbmRpY2FvLAogICAgICAgICAgICAgICBnc2VhX2VucmljaG1lbnQgPSAiSW1tdW5lR08iKQogICAgfSwgZXJyb3IgPSBmdW5jdGlvbihlKSB7CiAgICAgIHJldHVybihOVUxMKSAgIyBSZXRvcm5hIE5VTEwgY2FzbyBvY29ycmEgbyBlcnJvCiAgICB9KQoKICAgIGlmICghaXMubnVsbChpbW11bmVfR09fZ3NlYSkpIHsKICAgICAgcmVzdWx0YWRvc1tbcGFzdGUoY29uZGljYW8sICJJbW11bmVHTyIsIHNlcCA9ICJfIildXSA8LSBpbW11bmVfR09fZ3NlYQogICAgfQoKICAgICMjIyMjIyMjIyMjIyBDRUxMIE1BUktFUgogICAgY2VsbF9tYXJrZXJfZ3NlYSA8LSB0cnlDYXRjaCh7CiAgICAgIEdTRUEobG9nZm9sZGNoYW5nZV9jb25kaWNhbywKICAgICAgICAgICBURVJNMkdFTkUgPSBDZWxsTWFya2VyX2dlbmVzLAogICAgICAgICAgIG1pbkdTU2l6ZSA9IDEsCiAgICAgICAgICAgbWF4R1NTaXplID0gMTAwMCwKICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjI1LAogICAgICAgICAgIHBBZGp1c3RNZXRob2QgPSAiQkgiKSAlPiUKICAgICAgICBhcy5kYXRhLmZyYW1lKCkgJT4lCiAgICAgICAgYXJyYW5nZShxdmFsdWUpICU+JQogICAgICAgIG11dGF0ZShjb25kaXRpb24gPSBjb25kaWNhbywKICAgICAgICAgICAgICAgZ3NlYV9lbnJpY2htZW50ID0gIkNlbGxNYXJrZXIiKQogICAgfSwgZXJyb3IgPSBmdW5jdGlvbihlKSB7CiAgICAgIHJldHVybihOVUxMKSAgIyBSZXRvcm5hIE5VTEwgY2FzbyBvY29ycmEgbyBlcnJvCiAgICB9KQoKICAgIGlmICghaXMubnVsbChjZWxsX21hcmtlcl9nc2VhKSkgewogICAgICByZXN1bHRhZG9zW1twYXN0ZShjb25kaWNhbywgIkNlbGxNYXJrZXIiLCBzZXAgPSAiXyIpXV0gPC0gY2VsbF9tYXJrZXJfZ3NlYQogICAgfQoKICAgICMjIyMjIyMjIyMjIyBWQVggU0lHIERCCiAgICB2YXhfc2lnX2dzZWEgPC0gdHJ5Q2F0Y2goewogICAgICBlbnJpY2hlcihnZW5lc19jb25kaWNhbywKICAgICAgICAgICAgICAgVEVSTTJHRU5FID0gdmF4X3NpZ19nZW5lcywKICAgICAgICAgICAgICAgbWluR1NTaXplID0gMSwKICAgICAgICAgICAgICAgbWF4R1NTaXplID0gMTAwMCwKICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4yNSwKICAgICAgICAgICAgICAgcEFkanVzdE1ldGhvZCA9ICJCSCIpICU+JQogICAgICAgIGFzLmRhdGEuZnJhbWUoKSAlPiUKICAgICAgICBhcnJhbmdlKHF2YWx1ZSkgJT4lCiAgICAgICAgbXV0YXRlKGNvbmRpdGlvbiA9IGNvbmRpY2FvLAogICAgICAgICAgICAgICBnc2VhX2VucmljaG1lbnQgPSAiVkFYU2lnIikKICAgIH0sIGVycm9yID0gZnVuY3Rpb24oZSkgewogICAgICByZXR1cm4oTlVMTCkgICMgUmV0b3JuYSBOVUxMIGNhc28gb2NvcnJhIG8gZXJybwogICAgfSkKCiAgICBpZiAoIWlzLm51bGwodmF4X3NpZ19nc2VhKSkgewogICAgICByZXN1bHRhZG9zW1twYXN0ZShjb25kaWNhbywgIlZBWFNpZyIsIHNlcCA9ICJfIildXSA8LSB2YXhfc2lnX2dzZWEKICAgIH0KICB9CgogICMgQ29tYmluYXIgdG9kb3Mgb3MgcmVzdWx0YWRvcyBlbSB1bSDDum5pY28gZGF0YWZyYW1lCiAgcmVzdWx0YWRvX2ZpbmFsIDwtIGJpbmRfcm93cyhyZXN1bHRhZG9zKQoKICByZXR1cm4ocmVzdWx0YWRvX2ZpbmFsKQp9CgoKIyBDaGFtYXIgYSBmdW7Dp8OjbyBwYXJhIGV4ZWN1dGFyIGFzIGFuw6FsaXNlcyBwYXJhIGNhZGEgdmFsb3IgZGEgY29sdW5hICJjb25kaXRpb24iCmFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkX0dTRUFfQUxMIDwtIEdTRUFfQUxMKGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkLCBJbW11bmVfR09fVDJHLCBDZWxsTWFya2VyX2dlbmVzLCB2YXhfc2lnX2dlbmVzKQoKYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWRfR1NFQV9BTEwgPSBhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZF9HU0VBX0FMTCAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCJkZWxldGUiKSAlPiUgCiAgc2VsZWN0KC1kZWxldGUsIC1EZXNjcmlwdGlvbikKCndyaXRlLmNzdihhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZF9HU0VBX0FMTCwgZmlsZSA9ICJhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZF9HU0VBX0FMTF8yOS0xMS0yMy5jc3YiKQoKIyBTYWx2YXIgb3MgcmVzdWx0YWRvcyBlbSBhcnF1aXZvcyBzZXBhcmFkb3MgcG9yIGNvbmRpw6fDo28gZSB0aXBvIGRlIGFuw6FsaXNlCmZvciAoaSBpbiAxOm5yb3coYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWRfR1NFQV9BTEwpKSB7CiAgd3JpdGUuY3N2KGFsbF9kZWdzX3BfMDVfdmFjX2luZmVjdGVkX0dTRUFfQUxMW2ksIF0sIGZpbGUgPSBwYXN0ZShhbGxfZGVnc19wXzA1X3ZhY19pbmZlY3RlZF9HU0VBX0FMTFtpLCAiY29uZGl0aW9uIl0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsX2RlZ3NfcF8wNV92YWNfaW5mZWN0ZWRfR1NFQV9BTExbaSwgImdzZWFfZW5yaWNobWVudCJdLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIuY3N2Iiwgc2VwID0gIl8iKSkKfQoKYGBgCgo=